change to behavior of Autofill: If domain and package are not "compatible" (i.e. package is a trusted web browser or later DAL verification succeeded), allow to insert the credentials for the domain (no longer the package), but ask the user if he trusts the app.
This commit is contained in:
@@ -1230,4 +1230,10 @@ Initial public release
|
||||
<string name="switch_ime_text">Please activate the Keepass2Android keyboard.</string>
|
||||
<string name="switch_ime_reopen">Retry</string>
|
||||
|
||||
|
||||
<string name="AutofillWarning_title">Security Alert: Unrecognized domain/package link</string>
|
||||
<string name="AutofillWarning_Intro">You are about to insert credentials for domain "%1$s" into the app with package name "%2$s".</string>
|
||||
<string name="AutofillWarning_FillDomainInUntrustedApp">If you trust "%2$s" to belong to "%1$s" or you trust the app "%2$s" not to misuse the credentials (e.g. because it is a trusted browser app), it is ok to continue. If not, please cancel.</string>
|
||||
<string name="AutofillWarning_continue">Security Alert: Unrecognized domain/package link</string>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -16,8 +16,13 @@ namespace keepass2android.services.AutofillBase
|
||||
{
|
||||
public interface IAutofillIntentBuilder
|
||||
{
|
||||
IntentSender GetAuthIntentSenderForResponse(Context context, string query, bool isManualRequest, bool autoReturnFromQuery);
|
||||
IntentSender GetDisableIntentSenderForResponse(Context context, string query, bool isManualRequest, bool isDisable);
|
||||
IntentSender GetAuthIntentSenderForResponse(Context context, string query, string queryDomain, string queryPackage,
|
||||
bool isManualRequest, bool autoReturnFromQuery, AutofillServiceBase.DisplayWarning warning);
|
||||
|
||||
IntentSender GetAuthIntentSenderForWarning(Context context, string query, string queryDomain, string queryPackage, AutofillServiceBase.DisplayWarning warning);
|
||||
|
||||
IntentSender GetDisableIntentSenderForResponse(Context context, string query,
|
||||
bool isManualRequest, bool isDisable);
|
||||
Intent GetRestartAppIntent(Context context);
|
||||
|
||||
int AppIconResource { get; }
|
||||
@@ -90,7 +95,7 @@ namespace keepass2android.services.AutofillBase
|
||||
Log.Warn(CommonUtil.Tag, "Cancel autofill not implemented yet.");
|
||||
};
|
||||
// Parse AutoFill data in Activity
|
||||
string query = null;
|
||||
StructureParser.AutofillTargetId query = null;
|
||||
var parser = new StructureParser(this, structure);
|
||||
try
|
||||
{
|
||||
@@ -112,13 +117,34 @@ namespace keepass2android.services.AutofillBase
|
||||
{
|
||||
var responseBuilder = new FillResponse.Builder();
|
||||
|
||||
var entryDataset = AddEntryDataset(query, parser);
|
||||
Dataset entryDataset = null;
|
||||
if (query.IncompatiblePackageAndDomain == false)
|
||||
{
|
||||
//domain and package are compatible. Use Domain if available and package otherwise. Can fill without warning.
|
||||
entryDataset = BuildEntryDataset(query.DomainOrPackage, query.WebDomain, query.PackageName, autofillIds, parser, DisplayWarning.None);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
//domain or package are incompatible. Don't show the entry. (Tried to do so first but behavior was not consistent)
|
||||
//entryDataset = BuildEntryDataset(query.WebDomain, query.WebDomain, query.PackageName, autofillIds, parser, DisplayWarning.FillDomainInUntrustedApp);
|
||||
}
|
||||
bool hasEntryDataset = entryDataset != null;
|
||||
if (entryDataset != null)
|
||||
responseBuilder.AddDataset(entryDataset);
|
||||
|
||||
AddQueryDataset(query, isManual, autofillIds, responseBuilder, !hasEntryDataset);
|
||||
AddDisableDataset(query, autofillIds, responseBuilder, isManual);
|
||||
if (query.WebDomain != null)
|
||||
AddQueryDataset(query.WebDomain,
|
||||
query.WebDomain, query.PackageName,
|
||||
isManual, autofillIds, responseBuilder, !hasEntryDataset, query.IncompatiblePackageAndDomain ? DisplayWarning.FillDomainInUntrustedApp : DisplayWarning.None);
|
||||
else
|
||||
AddQueryDataset(query.PackageNameWithPseudoSchema,
|
||||
query.WebDomain, query.PackageName,
|
||||
isManual, autofillIds, responseBuilder, !hasEntryDataset, DisplayWarning.None);
|
||||
|
||||
|
||||
AddDisableDataset(query.DomainOrPackage, autofillIds, responseBuilder, isManual);
|
||||
|
||||
if (PreferenceManager.GetDefaultSharedPreferences(this)
|
||||
.GetBoolean(GetString(Resource.String.OfferSaveCredentials_key), true))
|
||||
{
|
||||
@@ -138,22 +164,57 @@ namespace keepass2android.services.AutofillBase
|
||||
}
|
||||
}
|
||||
|
||||
private Dataset AddEntryDataset(string query, StructureParser parser)
|
||||
private Dataset BuildEntryDataset(string query, string queryDomain, string queryPackage, AutofillId[] autofillIds, StructureParser parser,
|
||||
DisplayWarning warning)
|
||||
{
|
||||
var filledAutofillFieldCollection = GetSuggestedEntry(query);
|
||||
if (filledAutofillFieldCollection == null)
|
||||
return null;
|
||||
int partitionIndex = AutofillHintsHelper.GetPartitionIndex(parser.AutofillFields.FocusedAutofillCanonicalHints.FirstOrDefault());
|
||||
FilledAutofillFieldCollection partitionData = AutofillHintsHelper.FilterForPartition(filledAutofillFieldCollection, partitionIndex);
|
||||
|
||||
return AutofillHelper.NewDataset(this, parser.AutofillFields, partitionData, IntentBuilder);
|
||||
if (warning == DisplayWarning.None)
|
||||
{
|
||||
//can return an actual dataset
|
||||
int partitionIndex = AutofillHintsHelper.GetPartitionIndex(parser.AutofillFields.FocusedAutofillCanonicalHints.FirstOrDefault());
|
||||
FilledAutofillFieldCollection partitionData = AutofillHintsHelper.FilterForPartition(filledAutofillFieldCollection, partitionIndex);
|
||||
|
||||
return AutofillHelper.NewDataset(this, parser.AutofillFields, partitionData, IntentBuilder);
|
||||
}
|
||||
else
|
||||
{
|
||||
//return an "auth" dataset (actually for just warning the user in case domain/package dont match)
|
||||
var sender = IntentBuilder.GetAuthIntentSenderForWarning(this, query, queryDomain, queryPackage, warning);
|
||||
var datasetName = filledAutofillFieldCollection.DatasetName;
|
||||
if (datasetName == null)
|
||||
return null;
|
||||
|
||||
RemoteViews presentation = AutofillHelper.NewRemoteViews(PackageName, datasetName, AppNames.LauncherIcon);
|
||||
|
||||
var datasetBuilder = new Dataset.Builder(presentation);
|
||||
datasetBuilder.SetAuthentication(sender);
|
||||
//need to add placeholders so we can directly fill after ChooseActivity
|
||||
foreach (var autofillId in autofillIds)
|
||||
{
|
||||
datasetBuilder.SetValue(autofillId, AutofillValue.ForText("PLACEHOLDER"));
|
||||
}
|
||||
|
||||
return datasetBuilder.Build();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected abstract FilledAutofillFieldCollection GetSuggestedEntry(string query);
|
||||
|
||||
private void AddQueryDataset(string query, bool isManual, AutofillId[] autofillIds, FillResponse.Builder responseBuilder, bool autoReturnFromQuery)
|
||||
public enum DisplayWarning
|
||||
{
|
||||
var sender = IntentBuilder.GetAuthIntentSenderForResponse(this, query, isManual, autoReturnFromQuery);
|
||||
None,
|
||||
FillDomainInUntrustedApp, //display a warning that the user is filling credentials for a domain inside an app not marked as trusted browser
|
||||
|
||||
}
|
||||
|
||||
private void AddQueryDataset(string query, string queryDomain, string queryPackage, bool isManual, AutofillId[] autofillIds, FillResponse.Builder responseBuilder, bool autoReturnFromQuery, DisplayWarning warning)
|
||||
{
|
||||
var sender = IntentBuilder.GetAuthIntentSenderForResponse(this, query, queryDomain, queryPackage, isManual, autoReturnFromQuery, warning);
|
||||
RemoteViews presentation = AutofillHelper.NewRemoteViews(PackageName,
|
||||
GetString(Resource.String.autofill_sign_in_prompt), AppNames.LauncherIcon);
|
||||
|
||||
@@ -219,13 +280,13 @@ namespace keepass2android.services.AutofillBase
|
||||
responseBuilder.AddDataset(datasetBuilder.Build());
|
||||
}
|
||||
|
||||
private bool CanAutofill(string query, bool isManual)
|
||||
private bool CanAutofill(StructureParser.AutofillTargetId query, bool isManual)
|
||||
{
|
||||
if (query == "androidapp://android" || query == "androidapp://" + this.PackageName)
|
||||
if (query.PackageNameWithPseudoSchema == "androidapp://android" || query.PackageNameWithPseudoSchema == "androidapp://" + this.PackageName)
|
||||
return false;
|
||||
if (!isManual)
|
||||
{
|
||||
var isQueryDisabled = IsQueryDisabled(query);
|
||||
var isQueryDisabled = IsQueryDisabled(query.DomainOrPackage);
|
||||
if (isQueryDisabled)
|
||||
return false;
|
||||
}
|
||||
@@ -251,7 +312,7 @@ namespace keepass2android.services.AutofillBase
|
||||
}
|
||||
|
||||
var parser = new StructureParser(this, structure);
|
||||
string query = parser.ParseForSave();
|
||||
var query = parser.ParseForSave();
|
||||
try
|
||||
{
|
||||
HandleSaveRequest(parser, query);
|
||||
@@ -264,7 +325,7 @@ namespace keepass2android.services.AutofillBase
|
||||
|
||||
}
|
||||
|
||||
protected abstract void HandleSaveRequest(StructureParser parser, string query);
|
||||
protected abstract void HandleSaveRequest(StructureParser parser, StructureParser.AutofillTargetId query);
|
||||
|
||||
|
||||
public override void OnConnected()
|
||||
|
||||
@@ -12,6 +12,7 @@ using Java.Util;
|
||||
using keepass2android.services.AutofillBase.model;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using AlertDialog = Android.App.AlertDialog;
|
||||
|
||||
namespace keepass2android.services.AutofillBase
|
||||
{
|
||||
@@ -22,8 +23,12 @@ namespace keepass2android.services.AutofillBase
|
||||
|
||||
|
||||
public static string ExtraQueryString => "EXTRA_QUERY_STRING";
|
||||
public static string ExtraQueryPackageString => "EXTRA_QUERY_PACKAGE_STRING";
|
||||
public static string ExtraQueryDomainString => "EXTRA_QUERY_DOMAIN_STRING";
|
||||
public static string ExtraUseLastOpenedEntry => "EXTRA_USE_LAST_OPENED_ENTRY"; //if set to true, no query UI is displayed. Can be used to just show a warning
|
||||
public static string ExtraIsManualRequest => "EXTRA_IS_MANUAL_REQUEST";
|
||||
public static string ExtraAutoReturnFromQuery => "EXTRA_AUTO_RETURN_FROM_QUERY";
|
||||
public static string ExtraDisplayWarning => "EXTRA_DISPLAY_WARNING";
|
||||
|
||||
public int RequestCodeQuery => 6245;
|
||||
|
||||
@@ -46,12 +51,56 @@ namespace keepass2android.services.AutofillBase
|
||||
RestartApp();
|
||||
return;
|
||||
}
|
||||
if (Intent.HasExtra(ExtraDisplayWarning))
|
||||
{
|
||||
AutofillServiceBase.DisplayWarning warning =
|
||||
(AutofillServiceBase.DisplayWarning)Intent.GetIntExtra(ExtraDisplayWarning, (int)AutofillServiceBase.DisplayWarning.None);
|
||||
if (warning != AutofillServiceBase.DisplayWarning.None)
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.SetTitle(this.GetString(Resource.String.AutofillWarning_title));
|
||||
|
||||
var i = GetQueryIntent(requestedUrl, Intent.GetBooleanExtra(ExtraAutoReturnFromQuery, true));
|
||||
StartActivityForResult(i, RequestCodeQuery);
|
||||
builder.SetMessage(
|
||||
GetString(Resource.String.AutofillWarning_Intro, new Java.Lang.Object[] { Intent.GetStringExtra(ExtraQueryDomainString), Intent.GetStringExtra(ExtraQueryPackageString) })
|
||||
+ " " +
|
||||
this.GetString(Resource.String.AutofillWarning_FillDomainInUntrustedApp, new Java.Lang.Object[] { Intent.GetStringExtra(ExtraQueryDomainString), Intent.GetStringExtra(ExtraQueryPackageString) }));
|
||||
|
||||
builder.SetPositiveButton(this.GetString(Resource.String.Continue),
|
||||
(dlgSender, dlgEvt) =>
|
||||
{
|
||||
Proceed();
|
||||
|
||||
});
|
||||
|
||||
builder.SetNegativeButton(this.GetString(Resource.String.cancel), (dlgSender, dlgEvt) =>
|
||||
{
|
||||
Finish();
|
||||
});
|
||||
|
||||
Dialog dialog = builder.Create();
|
||||
dialog.Show();
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
Proceed();
|
||||
}
|
||||
|
||||
protected abstract Intent GetQueryIntent(string requestedUrl, bool autoReturnFromQuery);
|
||||
private void Proceed()
|
||||
{
|
||||
string requestedUrl = Intent.GetStringExtra(ExtraQueryString);
|
||||
|
||||
var i = GetQueryIntent(requestedUrl, Intent.GetBooleanExtra(ExtraAutoReturnFromQuery, true), Intent.GetBooleanExtra(ExtraUseLastOpenedEntry, false));
|
||||
if (i == null)
|
||||
{
|
||||
//GetQueryIntent returns null if no query is required
|
||||
ReturnSuccess();
|
||||
}
|
||||
else
|
||||
StartActivityForResult(i, RequestCodeQuery);
|
||||
}
|
||||
|
||||
protected abstract Intent GetQueryIntent(string requestedUrl, bool autoReturnFromQuery, bool useLastOpenedEntry);
|
||||
|
||||
protected void RestartApp()
|
||||
{
|
||||
@@ -100,15 +149,24 @@ namespace keepass2android.services.AutofillBase
|
||||
if (requestCode == RequestCodeQuery)
|
||||
{
|
||||
if (resultCode == ExpectedActivityResult)
|
||||
OnSuccess(GetDataset(data), Intent.GetBooleanExtra(ExtraIsManualRequest, false));
|
||||
ReturnSuccess();
|
||||
else
|
||||
OnFailure();
|
||||
Finish();
|
||||
{
|
||||
OnFailure();
|
||||
Finish();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void ReturnSuccess()
|
||||
{
|
||||
OnSuccess(GetDataset(), Intent.GetBooleanExtra(ExtraIsManualRequest, false));
|
||||
Finish();
|
||||
}
|
||||
|
||||
protected virtual Result ExpectedActivityResult
|
||||
{
|
||||
get { return Result.Ok; }
|
||||
@@ -117,7 +175,7 @@ namespace keepass2android.services.AutofillBase
|
||||
/// <summary>
|
||||
/// Creates the FilledAutofillFieldCollection from the intent returned from the query activity
|
||||
/// </summary>
|
||||
protected abstract FilledAutofillFieldCollection GetDataset(Intent data);
|
||||
protected abstract FilledAutofillFieldCollection GetDataset();
|
||||
|
||||
public abstract IAutofillIntentBuilder IntentBuilder { get; }
|
||||
|
||||
|
||||
@@ -38,24 +38,52 @@ namespace keepass2android.services.AutofillBase
|
||||
domainSuffixParserCache = new PublicSuffixRuleCache(context);
|
||||
}
|
||||
|
||||
public string ParseForFill(bool isManual)
|
||||
public class AutofillTargetId
|
||||
{
|
||||
public string PackageName { get; set; }
|
||||
|
||||
public string PackageNameWithPseudoSchema
|
||||
{
|
||||
get { return "androidapp://" + PackageName; }
|
||||
}
|
||||
|
||||
public string WebDomain { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If PackageName and WebDomain are not compatible (by DAL or because PackageName is a trusted browser in which case we treat all domains as "compatible"
|
||||
/// we need to issue a warning. If we would fill credentials for the package, a malicious website could try to get credentials for the app.
|
||||
/// If we would fill credentials for the domain, a malicious app could get credentials for the domain.
|
||||
/// </summary>
|
||||
public bool IncompatiblePackageAndDomain { get; set; }
|
||||
|
||||
public string DomainOrPackage
|
||||
{
|
||||
get
|
||||
{
|
||||
return WebDomain ?? PackageNameWithPseudoSchema;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public AutofillTargetId ParseForFill(bool isManual)
|
||||
{
|
||||
return Parse(true, isManual);
|
||||
}
|
||||
|
||||
public string ParseForSave()
|
||||
public AutofillTargetId ParseForSave()
|
||||
{
|
||||
return Parse(false, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Traverse AssistStructure and add ViewNode metadata to a flat list.
|
||||
/// </summary>
|
||||
/// <returns>The parse.</returns>
|
||||
/// <param name="forFill">If set to <c>true</c> for fill.</param>
|
||||
/// <param name="isManualRequest"></param>
|
||||
string Parse(bool forFill, bool isManualRequest)
|
||||
{
|
||||
/// <summary>
|
||||
/// Traverse AssistStructure and add ViewNode metadata to a flat list.
|
||||
/// </summary>
|
||||
/// <returns>The parse.</returns>
|
||||
/// <param name="forFill">If set to <c>true</c> for fill.</param>
|
||||
/// <param name="isManualRequest"></param>
|
||||
AutofillTargetId Parse(bool forFill, bool isManualRequest)
|
||||
{
|
||||
AutofillTargetId result = new AutofillTargetId();
|
||||
CommonUtil.logd("Parsing structure for " + Structure.ActivityComponent);
|
||||
var nodes = Structure.WindowNodeCount;
|
||||
ClientFormData = new FilledAutofillFieldCollection();
|
||||
@@ -144,23 +172,21 @@ namespace keepass2android.services.AutofillBase
|
||||
}
|
||||
|
||||
|
||||
|
||||
String packageName = Structure.ActivityComponent.PackageName;
|
||||
result.WebDomain = webDomain;
|
||||
result.PackageName = Structure.ActivityComponent.PackageName;
|
||||
if (!string.IsNullOrEmpty(webDomain))
|
||||
{
|
||||
bool valid = Kp2aDigitalAssetLinksDataSource.Instance.IsValid(mContext, webDomain, packageName);
|
||||
if (!valid)
|
||||
{
|
||||
CommonUtil.loge($"DAL verification failed for {packageName}/{webDomain}");
|
||||
webDomain = null;
|
||||
}
|
||||
result.IncompatiblePackageAndDomain = !Kp2aDigitalAssetLinksDataSource.Instance.IsValid(mContext, webDomain, result.PackageName);
|
||||
if (result.IncompatiblePackageAndDomain)
|
||||
{
|
||||
CommonUtil.loge($"DAL verification failed for {result.PackageName}/{result.WebDomain}");
|
||||
}
|
||||
}
|
||||
if (string.IsNullOrEmpty(webDomain))
|
||||
else
|
||||
{
|
||||
webDomain = "androidapp://" + packageName;
|
||||
CommonUtil.logd("no web domain. Using package name.");
|
||||
}
|
||||
return webDomain;
|
||||
result.IncompatiblePackageAndDomain = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
private static readonly HashSet<string> _passwordHints = new HashSet<string> { "password","passwort" };
|
||||
private static bool HasPasswordHint(AssistStructure.ViewNode f)
|
||||
|
||||
@@ -24,8 +24,12 @@ namespace keepass2android.services.Kp2aAutofill
|
||||
Permission = "keepass2android." + AppNames.PackagePart + ".permission.Kp2aChooseAutofill")]
|
||||
public class ChooseForAutofillActivity : ChooseForAutofillActivityBase
|
||||
{
|
||||
protected override Intent GetQueryIntent(string requestedUrl, bool autoReturnFromQuery)
|
||||
protected override Intent GetQueryIntent(string requestedUrl, bool autoReturnFromQuery, bool useLastOpenedEntry)
|
||||
{
|
||||
if (useLastOpenedEntry && (App.Kp2a.LastOpenedEntry?.SearchUrl == requestedUrl))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
//launch FileSelectActivity (which is root of the stack (exception: we're even below!)) with the appropriate task.
|
||||
//will return the results later
|
||||
Intent i = new Intent(this, typeof(SelectCurrentDbActivity));
|
||||
@@ -37,7 +41,7 @@ namespace keepass2android.services.Kp2aAutofill
|
||||
|
||||
protected override Result ExpectedActivityResult => KeePass.ExitCloseAfterTaskComplete;
|
||||
|
||||
protected override FilledAutofillFieldCollection GetDataset(Intent data)
|
||||
protected override FilledAutofillFieldCollection GetDataset()
|
||||
{
|
||||
if (App.Kp2a.CurrentDb==null || (App.Kp2a.QuickLocked))
|
||||
return null;
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace keepass2android.services
|
||||
return null;
|
||||
}
|
||||
|
||||
protected override void HandleSaveRequest(StructureParser parser, string query)
|
||||
protected override void HandleSaveRequest(StructureParser parser, StructureParser.AutofillTargetId query)
|
||||
{
|
||||
var intent = new Intent(this, typeof(SelectCurrentDbActivity));
|
||||
intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.ClearTop | ActivityFlags.SingleTop);
|
||||
@@ -53,7 +53,7 @@ namespace keepass2android.services
|
||||
|
||||
}
|
||||
if (query != null)
|
||||
outputFields.TryAdd(PwDefs.UrlField, query);
|
||||
outputFields.TryAdd(PwDefs.UrlField, query.WebDomain);
|
||||
|
||||
JSONObject jsonOutput = new JSONObject(outputFields);
|
||||
var jsonOutputStr = jsonOutput.ToString();
|
||||
|
||||
@@ -15,16 +15,33 @@ namespace keepass2android.services
|
||||
class Kp2aAutofillIntentBuilder: IAutofillIntentBuilder
|
||||
{
|
||||
|
||||
public IntentSender GetAuthIntentSenderForResponse(Context context, string query, bool isManualRequest, bool autoReturnFromQuery)
|
||||
public IntentSender GetAuthIntentSenderForResponse(Context context, string query, string queryDomain, string queryPackage,
|
||||
bool isManualRequest, bool autoReturnFromQuery, AutofillServiceBase.DisplayWarning warning)
|
||||
{
|
||||
Intent intent = new Intent(context, typeof(ChooseForAutofillActivity));
|
||||
intent.PutExtra(ChooseForAutofillActivityBase.ExtraQueryString, query);
|
||||
intent.PutExtra(ChooseForAutofillActivityBase.ExtraQueryDomainString, queryDomain);
|
||||
intent.PutExtra(ChooseForAutofillActivityBase.ExtraQueryPackageString, queryPackage);
|
||||
intent.PutExtra(ChooseForAutofillActivityBase.ExtraIsManualRequest, isManualRequest);
|
||||
intent.PutExtra(ChooseForAutofillActivityBase.ExtraAutoReturnFromQuery, autoReturnFromQuery);
|
||||
intent.PutExtra(ChooseForAutofillActivityBase.ExtraDisplayWarning, (int)warning);
|
||||
return PendingIntent.GetActivity(context, 0, intent, PendingIntentFlags.CancelCurrent).IntentSender;
|
||||
}
|
||||
|
||||
public IntentSender GetDisableIntentSenderForResponse(Context context, string query, bool isManualRequest, bool isDisable)
|
||||
public IntentSender GetAuthIntentSenderForWarning(Context context, string query, string queryDomain, string queryPackage,
|
||||
AutofillServiceBase.DisplayWarning warning)
|
||||
{
|
||||
Intent intent = new Intent(context, typeof(ChooseForAutofillActivity));
|
||||
intent.PutExtra(ChooseForAutofillActivityBase.ExtraQueryString, query);
|
||||
intent.PutExtra(ChooseForAutofillActivityBase.ExtraQueryDomainString, queryDomain);
|
||||
intent.PutExtra(ChooseForAutofillActivityBase.ExtraQueryPackageString, queryPackage);
|
||||
intent.PutExtra(ChooseForAutofillActivityBase.ExtraDisplayWarning, (int)warning);
|
||||
intent.PutExtra(ChooseForAutofillActivityBase.ExtraUseLastOpenedEntry, true);
|
||||
return PendingIntent.GetActivity(context, 0, intent, PendingIntentFlags.CancelCurrent).IntentSender;
|
||||
}
|
||||
|
||||
public IntentSender GetDisableIntentSenderForResponse(Context context, string query,
|
||||
bool isManualRequest, bool isDisable)
|
||||
{
|
||||
Intent intent = new Intent(context, typeof(DisableAutofillForQueryActivity));
|
||||
intent.PutExtra(ChooseForAutofillActivityBase.ExtraQueryString, query);
|
||||
|
||||
Reference in New Issue
Block a user