MyAutofillService

 avatar
Trrieu112233
java
a month ago
8.4 kB
6
Indexable
package com.example.testapp2;

import android.app.PendingIntent;
import android.app.assist.AssistStructure;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.service.autofill.AutofillService;
import android.service.autofill.Dataset;
import android.service.autofill.FillCallback;
import android.service.autofill.FillContext;
import android.service.autofill.FillRequest;
import android.service.autofill.FillResponse;
import android.service.autofill.SaveCallback;
import android.service.autofill.SaveInfo;
import android.service.autofill.SaveRequest;
import android.util.Log;
import android.view.View;
import android.view.autofill.AutofillId;
import android.view.autofill.AutofillValue;
import android.widget.RemoteViews;

import org.json.JSONArray;
import org.json.JSONObject;

import java.util.List;

public class MyAutofillService extends AutofillService {
    private static String TAG_FILL = "fill_test";
    private static String TAG_SAVE = "save_test";

    @Override
    public void onFillRequest(FillRequest request, android.os.CancellationSignal cancellationSignal, FillCallback callback){
        Log.d(TAG_FILL, "Begin fill task");
        // Lay package name app A
        AssistStructure structure = request.getFillContexts().get(request.getFillContexts().size() - 1).getStructure();
        String callingPkg = structure.getActivityComponent().getPackageName();
        FillResponse.Builder responseBuilder = new FillResponse.Builder();

        // Tim ID username va password dua vao hint
        AutofillId userId = findIdByHint(structure, View.AUTOFILL_HINT_USERNAME);
        if(userId == null){
            userId = findIdByHint(structure, View.AUTOFILL_HINT_PHONE);
        }
        AutofillId passwordId = findIdByHint(structure, View.AUTOFILL_HINT_PASSWORD);

        if(userId != null && passwordId != null){
            SaveInfo saveInfo = new SaveInfo.Builder(
                    SaveInfo.SAVE_DATA_TYPE_PASSWORD,
                    new AutofillId[] {userId, passwordId})
                    .build();
            responseBuilder.setSaveInfo(saveInfo);

            // goi sharedPref liet ke danh sach user
            Log.d(TAG_FILL, "Begin get account list sharedPref");
            JSONArray rawUsers = JsonPrefHelper.getAccountsArray(this);
            try {
                int requestCode = 0;
                for (int i = 0; i < rawUsers.length(); i++) {
                    JSONObject obj = rawUsers.getJSONObject(i);
                    String savedPkg = obj.getString("package");
                    if(savedPkg.equals(callingPkg)) {
                        String popup_user = obj.getString("username").trim();

                        Log.d(TAG_FILL, "Setup biometric auth for user " + popup_user);

                        Intent authIntent = new Intent(this, AuthActivity.class);
                        authIntent.putExtra("EXTRA_PKG", callingPkg);
                        authIntent.putExtra("EXTRA_USER", popup_user);
                        authIntent.putExtra("EXTRA_USER_ID", userId);
                        authIntent.putExtra("EXTRA_PASSWORD_ID", passwordId);

                        PendingIntent pendingIntent = PendingIntent.getActivity(
                                this,
                                requestCode ++,
                                authIntent,
                                PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);

                        RemoteViews presentation = new RemoteViews(getPackageName(), android.R.layout.simple_list_item_1);
                        presentation.setTextViewText(android.R.id.text1, "TEE: " + popup_user);

                        Dataset dataset = new Dataset.Builder()
                                .setValue(userId, AutofillValue.forText(popup_user), presentation)
                                .setValue(passwordId, null, presentation)
                                .setAuthentication(pendingIntent.getIntentSender())
                                .build();
                        responseBuilder.addDataset(dataset);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            callback.onSuccess(responseBuilder.build());
        } else {
            callback.onSuccess(null);
        }
    }

    @Override
    public void onSaveRequest(SaveRequest request, SaveCallback callback){
        Log.d(TAG_SAVE, "Begin save task");
        // Lay cau truc man hinh app A
        List<FillContext> contexts = request.getFillContexts();
        AssistStructure structure = contexts.get(contexts.size() - 1).getStructure();

        //Lay package name app A
        String packageName = structure.getActivityComponent().getPackageName();
        // Trich xuat username va password
        String userId = findValueByHint(structure, View.AUTOFILL_HINT_USERNAME);
        if(userId == null){
            userId = findValueByHint(structure, View.AUTOFILL_HINT_PHONE);
        }
        String password = findValueByHint(structure, View.AUTOFILL_HINT_PASSWORD);
        String appname = getAppName(packageName);

        if(userId != null && password != null && !userId.isEmpty() && !password.isEmpty()){
            JsonPrefHelper.saveAccounts(this, packageName, appname, userId);
            Log.d(TAG_SAVE, "Begin execute command save");
            // ./ca save [package name] [userId] [password]
            new ExecuteCommandTask(this, true).executeSync("save", packageName, userId, password);
            callback.onSuccess();
        } else {
            callback.onFailure("Cannot find data to save !");
        }
    }

    private String getAppName(String packageName){
        PackageManager packageManager = getPackageManager();
        try{
            ApplicationInfo info = packageManager.getApplicationInfo(packageName, 0);
            return (String) packageManager.getApplicationLabel(info);
        } catch (PackageManager.NameNotFoundException e){
            return packageName;
        }
    }
    private AutofillId findIdByHint(AssistStructure structure, String targetHint){
        int nodes = structure.getWindowNodeCount();
        for(int i = 0; i < nodes; i ++){
            AssistStructure.ViewNode node = structure.getWindowNodeAt(i).getRootViewNode();
            AutofillId id = traverseNode(node, targetHint);
            if(id != null) return id;
        }
        return null;
    }

    private AutofillId traverseNode(AssistStructure.ViewNode node, String targetHint){
        String[] hints = node.getAutofillHints();
        if(hints != null){
            for(String hint : hints){
                if(targetHint.equalsIgnoreCase(hint))
                    return node.getAutofillId();
            }
        }
        for(int i = 0; i < node.getChildCount(); i ++){
            AutofillId id = traverseNode(node.getChildAt(i), targetHint);
            if(id != null) return id;
        }
        return null;
    }

    private String findValueByHint(AssistStructure structure, String targetHint){
        int nodes = structure.getWindowNodeCount();
        for(int i = 0; i < nodes; i ++){
            AssistStructure.ViewNode node = structure.getWindowNodeAt(i).getRootViewNode();
            String value = traverseNodeForValue(node, targetHint);
            if(value != null) return value;
        }
        return null;
    }

    private String traverseNodeForValue(AssistStructure.ViewNode node, String targetHint){
        String[] hints = node.getAutofillHints();
        if(hints != null){
            for(String hint : hints){
                if(targetHint.equalsIgnoreCase(hint)){
                    AutofillValue value = node.getAutofillValue();
                    if(value != null && value.isText())
                        return value.getTextValue().toString();
                }
            }
        }
        for(int i = 0; i < node.getChildCount(); i ++){
            String value = traverseNodeForValue(node.getChildAt(i), targetHint);
            if(value != null) return value;
        }
        return null;
    }
}
Editor is loading...
Leave a Comment