Skip to content

Commit

Permalink
updated for ODP4
Browse files Browse the repository at this point in the history
  • Loading branch information
commonsguy committed Aug 7, 2017
1 parent 7bbb01d commit 7b32093
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 38 deletions.
7 changes: 7 additions & 0 deletions AutoFill/AutoFillLogger/README.markdown
@@ -0,0 +1,7 @@
This sample Android app demonstrates
an autofill service implementation, one that just logs all incoming data.

This app is covered in
[the chapter on autofill](https://commonsware.com/Android/previews/the-autofill-api)
in [*The Busy Coder's Guide to Android Development*](https://commonsware.com/Android/).

6 changes: 3 additions & 3 deletions AutoFill/AutoFillLogger/app/build.gradle
@@ -1,12 +1,12 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'


android { android {
compileSdkVersion 'android-O' compileSdkVersion 26
buildToolsVersion "25.0.3" buildToolsVersion "25.0.3"


defaultConfig { defaultConfig {
minSdkVersion 'O' minSdkVersion 26
targetSdkVersion 'O' targetSdkVersion 26
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"
} }
Expand Down
Expand Up @@ -20,6 +20,7 @@
import android.os.Environment; import android.os.Environment;
import android.service.autofill.AutofillService; import android.service.autofill.AutofillService;
import android.service.autofill.FillCallback; import android.service.autofill.FillCallback;
import android.service.autofill.FillContext;
import android.service.autofill.FillRequest; import android.service.autofill.FillRequest;
import android.service.autofill.FillResponse; import android.service.autofill.FillResponse;
import android.service.autofill.SaveCallback; import android.service.autofill.SaveCallback;
Expand All @@ -30,6 +31,7 @@
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
Expand All @@ -41,14 +43,6 @@ public class AutoFillLoggerService extends AutofillService {
SaveInfo.SAVE_DATA_TYPE_EMAIL_ADDRESS | SaveInfo.SAVE_DATA_TYPE_PASSWORD | SaveInfo.SAVE_DATA_TYPE_EMAIL_ADDRESS | SaveInfo.SAVE_DATA_TYPE_PASSWORD |
SaveInfo.SAVE_DATA_TYPE_USERNAME; SaveInfo.SAVE_DATA_TYPE_USERNAME;


@Override
public void onFillRequest(AssistStructure assistStructure, Bundle extras,
int whatever,
CancellationSignal cancellationSignal,
FillCallback fillCallback) {
// deprecated?
}

@Override @Override
public void onFillRequest(FillRequest request, public void onFillRequest(FillRequest request,
CancellationSignal cancellationSignal, CancellationSignal cancellationSignal,
Expand All @@ -63,16 +57,22 @@ public void onFillRequest(FillRequest request,


File logDir=getLogDir(extras); File logDir=getLogDir(extras);
Set<AutofillId> ids=new HashSet<>(); Set<AutofillId> ids=new HashSet<>();
AssistStructure assistStructure=request.getStructure();
AutofillId first=null; AutofillId first=null;
ArrayList<AssistStructure> assistStructures=new ArrayList<>();


for (int i=0; i<assistStructure.getWindowNodeCount(); i++) { for (FillContext fillContext : request.getFillContexts()) {
AssistStructure.WindowNode node=assistStructure.getWindowNodeAt(i); AssistStructure assistStructure=fillContext.getStructure();


AutofillId temp=collectViewIds(node.getRootViewNode(), ids); assistStructures.add(assistStructure);


if (first==null) { for (int i=0; i<assistStructure.getWindowNodeCount(); i++) {
first=temp; AssistStructure.WindowNode node=assistStructure.getWindowNodeAt(i);

AutofillId temp=collectViewIds(node.getRootViewNode(), ids);

if (first==null) {
first=temp;
}
} }
} }


Expand All @@ -86,7 +86,7 @@ public void onFillRequest(FillRequest request,
FillResponse.Builder b=new FillResponse.Builder(); FillResponse.Builder b=new FillResponse.Builder();


b.setSaveInfo(saveInfo); b.setSaveInfo(saveInfo);
b.setExtras(extras); b.setClientState(extras);


Log.d(getClass().getSimpleName(), Log.d(getClass().getSimpleName(),
String.format("onFillRequest() called, saving %d fields", ids.size())); String.format("onFillRequest() called, saving %d fields", ids.size()));
Expand All @@ -96,7 +96,7 @@ public void onFillRequest(FillRequest request,
try { try {
File log=File.createTempFile("fill-", ".json", logDir); File log=File.createTempFile("fill-", ".json", logDir);


new DumpThread.Fill(this, log, extras, assistStructure, fillCallback, new DumpThread.Fill(this, log, extras, assistStructures, fillCallback,
response).start(); response).start();
} }
catch (IOException e) { catch (IOException e) {
Expand All @@ -108,12 +108,6 @@ public void onFillRequest(FillRequest request,
} }
} }


@Override
public void onSaveRequest(AssistStructure assistStructure, Bundle extras,
SaveCallback saveCallback) {
// deprecated?
}

@Override @Override
public void onSaveRequest(SaveRequest request, SaveCallback saveCallback) { public void onSaveRequest(SaveRequest request, SaveCallback saveCallback) {
Log.d(getClass().getSimpleName(), "onSaveRequest() called"); Log.d(getClass().getSimpleName(), "onSaveRequest() called");
Expand Down
Expand Up @@ -31,6 +31,8 @@
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.lang.reflect.Array;
import java.util.List;
import java.util.Set; import java.util.Set;


abstract class DumpThread extends Thread { abstract class DumpThread extends Thread {
Expand Down Expand Up @@ -92,7 +94,7 @@ protected JSONObject dumpBundle(Bundle b, JSONObject json)
json.put(key, wrap(b.get(key))); json.put(key, wrap(b.get(key)));
} }


return (json); return(json);
} }


protected JSONObject dumpStructure(AssistStructure structure, JSONObject json) protected JSONObject dumpStructure(AssistStructure structure, JSONObject json)
Expand Down Expand Up @@ -127,7 +129,7 @@ protected JSONObject dumpStructureWindow(
dumpStructureNode(window.getRootViewNode(), dumpStructureNode(window.getRootViewNode(),
new JSONObject())); new JSONObject()));


return (json); return(json);
} }


private JSONObject dumpStructureNode( private JSONObject dumpStructureNode(
Expand Down Expand Up @@ -193,14 +195,14 @@ private JSONObject dumpStructureNode(
json.put("top", wrap(node.getTop())); json.put("top", wrap(node.getTop()));
json.put("transformation", json.put("transformation",
wrap(node.getTransformation())); wrap(node.getTransformation()));
json.put("url", wrap(node.getUrl()));
json.put("visibility", wrap(node.getVisibility())); json.put("visibility", wrap(node.getVisibility()));
json.put("webDomain", wrap(node.getWebDomain()));
json.put("width", wrap(node.getWidth())); json.put("width", wrap(node.getWidth()));


json.put("children", json.put("children",
dumpStructureNodes(node, new JSONArray())); dumpStructureNodes(node, new JSONArray()));


return (json); return(json);
} }


private JSONArray dumpStructureNodes( private JSONArray dumpStructureNodes(
Expand All @@ -211,15 +213,26 @@ private JSONArray dumpStructureNodes(
new JSONObject())); new JSONObject()));
} }


return (children); return(children);
} }


private Object wrap(Object thingy) { private Object wrap(Object thingy) {
if (thingy instanceof Array) {
Object[] array=(Object[])thingy;
JSONArray jsonArray=new JSONArray();

for (Object o : array) {
jsonArray.put(wrap(o));
}

return(jsonArray);
}

if (thingy instanceof CharSequence) { if (thingy instanceof CharSequence) {
return (JSONObject.wrap(thingy.toString())); return(JSONObject.wrap(thingy.toString()));
} }


return (JSONObject.wrap(thingy)); return(JSONObject.wrap(thingy));
} }


static class Save extends DumpThread { static class Save extends DumpThread {
Expand Down Expand Up @@ -278,16 +291,16 @@ static class Fill extends DumpThread {
private final FillCallback fillCallback; private final FillCallback fillCallback;
private final FillResponse response; private final FillResponse response;
private final Bundle data; private final Bundle data;
private final AssistStructure structure; private final List<AssistStructure> structures;


Fill(Context ctxt, File logDir, Bundle data, AssistStructure structure, Fill(Context ctxt, File logDir, Bundle data, List<AssistStructure> structures,
FillCallback fillCallback, FillResponse response) { FillCallback fillCallback, FillResponse response) {
super(ctxt, logDir); super(ctxt, logDir);


this.fillCallback=fillCallback; this.fillCallback=fillCallback;
this.response=response; this.response=response;
this.data=data; this.data=data;
this.structure=structure; this.structures=structures;
} }


@Override @Override
Expand All @@ -302,8 +315,14 @@ void writeTo(JSONObject json) {
} }
} }


JSONArray structureArray=new JSONArray();

try { try {
json.put("structure", dumpStructure(structure, new JSONObject())); json.put("structures", structureArray);

for (AssistStructure structure : structures) {
structureArray.put(dumpStructure(structure, new JSONObject()));
}
} }
catch (JSONException e) { catch (JSONException e) {
Log.e(getClass().getSimpleName(), Log.e(getClass().getSimpleName(),
Expand Down
Expand Up @@ -15,15 +15,52 @@
package com.commonsware.android.autofill.logger; package com.commonsware.android.autofill.logger;


import android.app.ListActivity; import android.app.ListActivity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.provider.Settings;
import android.view.autofill.AutofillManager;
import android.widget.Toast; import android.widget.Toast;


public class MainActivity extends ListActivity { public class MainActivity extends ListActivity {
private static final int REQUEST_ID=1337;

@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);


Toast.makeText(this, "Um, hi there!", Toast.LENGTH_LONG).show(); AutofillManager af=getSystemService(AutofillManager.class);

if (af.isAutofillSupported()) {
if (af.hasEnabledAutofillServices()) {
Toast.makeText(this, R.string.msg_ready, Toast.LENGTH_LONG).show();
finish();
}
else {
Uri uri=Uri.parse("package:"+getPackageName());
Intent i=new Intent(Settings.ACTION_REQUEST_SET_AUTOFILL_SERVICE, uri);

startActivityForResult(i, REQUEST_ID);
}
}
else {
Toast.makeText(this, R.string.msg_not_supported, Toast.LENGTH_LONG).show();
finish();
}
}

@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (requestCode==REQUEST_ID) {
if (resultCode==RESULT_OK) {
Toast.makeText(this, R.string.msg_ready, Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(this, R.string.msg_reject, Toast.LENGTH_LONG).show();
}
}

finish(); finish();
} }
} }
3 changes: 3 additions & 0 deletions AutoFill/AutoFillLogger/app/src/main/res/values/strings.xml
@@ -1,3 +1,6 @@
<resources> <resources>
<string name="app_name">AutoFill Logger Demo</string> <string name="app_name">AutoFill Logger Demo</string>
<string name="msg_ready">Carry on!</string>
<string name="msg_not_supported">Autofill is not supported!</string>
<string name="msg_reject">Well, *be* that way -- see what I care!</string>
</resources> </resources>
2 changes: 1 addition & 1 deletion AutoFill/AutoFillLogger/build.gradle
Expand Up @@ -5,7 +5,7 @@ buildscript {
jcenter() jcenter()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:2.3.2' classpath 'com.android.tools.build:gradle:2.3.3'


// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files
Expand Down

0 comments on commit 7b32093

Please sign in to comment.