Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8f21158f authored by Adrian Roos's avatar Adrian Roos
Browse files

Trust: Make setEnabledFeatures asynchronous

Unsynchronizes the call into app code from setEnabledFeatures,
replacing it with a callback mechanism. Also makes this actually
work by fixing the check in TrustManagerService to take into account
whitelisting.

Change-Id: I0831752cd2d3158eda9c8404a5569498f11ac2ac
parent 7861c663
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -25,5 +25,5 @@ import android.service.trust.ITrustAgentServiceCallback;
interface ITrustAgentService {
    oneway void onUnlockAttempt(boolean successful);
    oneway void setCallback(ITrustAgentServiceCallback callback);
    boolean setTrustAgentFeaturesEnabled(in Bundle options);
    oneway void setTrustAgentFeaturesEnabled(in Bundle options, IBinder token);
}
+2 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
package android.service.trust;

import android.os.Bundle;
import android.os.IBinder;
import android.os.UserHandle;

/**
@@ -26,4 +27,5 @@ oneway interface ITrustAgentServiceCallback {
    void grantTrust(CharSequence message, long durationMs, boolean initiatedByUser);
    void revokeTrust();
    void setManagingTrust(boolean managingTrust);
    void onSetTrustAgentFeaturesEnabledCompleted(boolean result, IBinder token);
}
+19 −5
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.content.pm.ServiceInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
import android.util.Slog;
@@ -94,6 +95,7 @@ public class TrustAgentService extends Service {
    public static final String KEY_FEATURES = "trust_agent_features";

    private static final int MSG_UNLOCK_ATTEMPT = 1;
    private static final int MSG_SET_TRUST_AGENT_FEATURES_ENABLED = 2;

    private ITrustAgentServiceCallback mCallback;

@@ -110,8 +112,20 @@ public class TrustAgentService extends Service {
                case MSG_UNLOCK_ATTEMPT:
                    onUnlockAttempt(msg.arg1 != 0);
                    break;
                case MSG_SET_TRUST_AGENT_FEATURES_ENABLED:
                    Bundle features = msg.peekData();
                    IBinder token = (IBinder) msg.obj;
                    boolean result = onSetTrustAgentFeaturesEnabled(features);
                    try {
                        synchronized (mLock) {
                            mCallback.onSetTrustAgentFeaturesEnabledCompleted(result, token);
                        }
                    } catch (RemoteException e) {
                        onError("calling onSetTrustAgentFeaturesEnabledCompleted()");
                    }
                    break;
            }
        }
        };
    };

    @Override
@@ -278,10 +292,10 @@ public class TrustAgentService extends Service {
        }

        @Override
        public boolean setTrustAgentFeaturesEnabled(Bundle features) {
            synchronized (mLock) {
                return onSetTrustAgentFeaturesEnabled(features);
            }
        public void setTrustAgentFeaturesEnabled(Bundle features, IBinder token) {
            Message msg = mHandler.obtainMessage(MSG_SET_TRUST_AGENT_FEATURES_ENABLED, token);
            msg.setData(features);
            msg.sendToTarget();
        }
    }

+47 −54
Original line number Diff line number Diff line
@@ -17,12 +17,11 @@
package com.android.server.trust;

import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -51,7 +50,7 @@ public class TrustAgentWrapper {
    private static final int MSG_REVOKE_TRUST = 2;
    private static final int MSG_TRUST_TIMEOUT = 3;
    private static final int MSG_RESTART_TIMEOUT = 4;
    private static final int MSG_DPM_CHANGED = 5;
    private static final int MSG_SET_TRUST_AGENT_FEATURES_COMPLETED = 5;
    private static final int MSG_MANAGING_TRUST = 6;

    /**
@@ -79,6 +78,7 @@ public class TrustAgentWrapper {
    private CharSequence mMessage;
    private boolean mTrustDisabledByDpm;
    private boolean mManagingTrust;
    private IBinder mSetTrustAgentFeaturesToken;

    private final Handler mHandler = new Handler() {
        @Override
@@ -121,8 +121,21 @@ public class TrustAgentWrapper {
                    unbind();
                    mTrustManagerService.resetAgent(mName, mUserId);
                    break;
                case MSG_DPM_CHANGED:
                    updateDevicePolicyFeatures(mName);
                case MSG_SET_TRUST_AGENT_FEATURES_COMPLETED:
                    IBinder token = (IBinder) msg.obj;
                    boolean result = msg.arg1 != 0;
                    if (mSetTrustAgentFeaturesToken == token) {
                        mSetTrustAgentFeaturesToken = null;
                        if (mTrustDisabledByDpm && result) {
                            if (DEBUG) Log.v(TAG, "Re-enabling agent because it acknowledged "
                                    + "enabled features: " + mName);
                            mTrustDisabledByDpm = false;
                            mTrustManagerService.updateTrust(mUserId);
                        }
                    } else {
                        if (DEBUG) Log.w(TAG, "Ignoring MSG_SET_TRUST_AGENT_FEATURES_COMPLETED "
                                + "with obsolete token: " + mName);
                    }
                    break;
                case MSG_MANAGING_TRUST:
                    mManagingTrust = msg.arg1 != 0;
@@ -161,6 +174,13 @@ public class TrustAgentWrapper {
            if (DEBUG) Slog.v(TAG, "managingTrust()");
            mHandler.obtainMessage(MSG_MANAGING_TRUST, managingTrust ? 1 : 0, 0).sendToTarget();
        }

        @Override
        public void onSetTrustAgentFeaturesEnabledCompleted(boolean result, IBinder token) {
            if (DEBUG) Slog.v(TAG, "onSetTrustAgentFeaturesEnabledCompleted(result=" + result);
            mHandler.obtainMessage(MSG_SET_TRUST_AGENT_FEATURES_COMPLETED,
                    result ? 1 : 0, 0, token).sendToTarget();
        }
    };

    private final ServiceConnection mConnection = new ServiceConnection() {
@@ -171,8 +191,7 @@ public class TrustAgentWrapper {
            mTrustAgentService = ITrustAgentService.Stub.asInterface(service);
            mTrustManagerService.mArchive.logAgentConnected(mUserId, name);
            setCallback(mCallback);
            updateDevicePolicyFeatures(name);
            watchForDpmChanges(true);
            updateDevicePolicyFeatures();
        }

        @Override
@@ -180,24 +199,13 @@ public class TrustAgentWrapper {
            if (DEBUG) Log.v(TAG, "TrustAgent disconnected : " + name.flattenToShortString());
            mTrustAgentService = null;
            mManagingTrust = false;
            mSetTrustAgentFeaturesToken = null;
            mTrustManagerService.mArchive.logAgentDied(mUserId, name);
            mHandler.sendEmptyMessage(MSG_REVOKE_TRUST);
            if (mBound) {
                scheduleRestart();
            }
            // mTrustDisabledByDpm maintains state
            watchForDpmChanges(false);
        }
    };

    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
                    .equals(intent.getAction())) {
                mHandler.sendEmptyMessage(MSG_DPM_CHANGED);
            }
        }
    };

@@ -241,49 +249,33 @@ public class TrustAgentWrapper {
        }
    }

    private void watchForDpmChanges(boolean start) {
        if (start) {
            final IntentFilter filter = new IntentFilter();
            filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
            filter.addAction(Intent.ACTION_USER_REMOVED);
            mContext.registerReceiver(mBroadcastReceiver, filter);
        } else {
            mContext.unregisterReceiver(mBroadcastReceiver);
        }
    }

    private boolean updateDevicePolicyFeatures(ComponentName name) {
    boolean updateDevicePolicyFeatures() {
        boolean trustDisabled = false;
        if (DEBUG) Slog.v(TAG, "updateDevicePolicyFeatures(" + name + ")");
        if (DEBUG) Slog.v(TAG, "updateDevicePolicyFeatures(" + mName + ")");
        try {
            if (mTrustAgentService != null) {
                DevicePolicyManager dpm =
                    (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
                if (dpm != null) {
                    // If trust disabled, only enable it if the options bundle is set and
                    // accepted by the TrustAgent.

                if ((dpm.getKeyguardDisabledFeatures(null)
                        & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0) {
                        List<String> features = dpm.getTrustAgentFeaturesEnabled(null, name);
                        if (DEBUG) Slog.v(TAG, "Detected trust agents disabled. Features = " + features);
                    List<String> features = dpm.getTrustAgentFeaturesEnabled(null, mName);
                    trustDisabled = true;
                    if (DEBUG) Slog.v(TAG, "Detected trust agents disabled. Features = "
                            + features);
                    if (features != null && features.size() > 0) {
                        Bundle bundle = new Bundle();
                        bundle.putStringArrayList(TrustAgentService.KEY_FEATURES,
                                (ArrayList<String>)features);
                        if (DEBUG) {
                                Slog.v(TAG, "TrustAgent " + name.flattenToShortString()
                                        + " disabled except "+ features);
                            Slog.v(TAG, "TrustAgent " + mName.flattenToShortString()
                                    + " disabled until it acknowledges "+ features);
                        }
                            trustDisabled = mTrustAgentService.setTrustAgentFeaturesEnabled(bundle);
                        } else {
                            if (DEBUG) Slog.v(TAG, "TrustAgent " + name + " disabled by flag");
                            trustDisabled = true; // trust agent should be disabled
                        mSetTrustAgentFeaturesToken = new Binder();
                        mTrustAgentService.setTrustAgentFeaturesEnabled(bundle,
                                mSetTrustAgentFeaturesToken);
                    }
                }
                } else {
                    Log.e(TAG, "Can't get DevicePolicyManagerService: is it running?",
                            new IllegalStateException("Stack trace:"));
                }
            }
        } catch (RemoteException e) {
            onError(e);
@@ -316,6 +308,7 @@ public class TrustAgentWrapper {
        mContext.unbindService(mConnection);
        mBound = false;
        mTrustAgentService = null;
        mSetTrustAgentFeaturesToken = null;
        mHandler.sendEmptyMessage(MSG_REVOKE_TRUST);
        mHandler.removeMessages(MSG_RESTART_TIMEOUT);
    }
+21 −4
Original line number Diff line number Diff line
@@ -157,7 +157,7 @@ public class TrustManagerService extends SystemService {
        dispatchOnTrustChanged(aggregateIsTrusted(userId), userId);
    }

    protected void refreshAgentList() {
    void refreshAgentList() {
        if (DEBUG) Slog.d(TAG, "refreshAgentList()");
        PackageManager pm = mContext.getPackageManager();

@@ -168,13 +168,13 @@ public class TrustManagerService extends SystemService {
        obsoleteAgents.addAll(mActiveAgents);

        for (UserInfo userInfo : userInfos) {
            int disabledFeatures = lockPatternUtils.getDevicePolicyManager()
                    .getKeyguardDisabledFeatures(null, userInfo.id);
            DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager();
            int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id);
            final boolean disableTrustAgents =
                    (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0;

            List<ComponentName> enabledAgents = lockPatternUtils.getEnabledTrustAgents(userInfo.id);
            if (disableTrustAgents || enabledAgents == null) {
            if (enabledAgents == null) {
                continue;
            }
            List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT,
@@ -193,6 +193,13 @@ public class TrustManagerService extends SystemService {
                ComponentName name = getComponentName(resolveInfo);
                if (!enabledAgents.contains(name)) continue;

                if (disableTrustAgents) {
                    List<String> features =
                            dpm.getTrustAgentFeaturesEnabled(null /* admin */, name);
                    // Disable agent if no features are enabled.
                    if (features == null || features.isEmpty()) continue;
                }

                AgentInfo agentInfo = new AgentInfo();
                agentInfo.component = name;
                agentInfo.userId = userInfo.id;
@@ -224,6 +231,15 @@ public class TrustManagerService extends SystemService {
        }
    }

    void updateDevicePolicyFeatures(int userId) {
        for (int i = 0; i < mActiveAgents.size(); i++) {
            AgentInfo info = mActiveAgents.valueAt(i);
            if (info.agent.isConnected()) {
                info.agent.updateDevicePolicyFeatures();
            }
        }
    }

    private void removeAgentsOfPackage(String packageName) {
        boolean trustMayHaveChanged = false;
        for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
@@ -587,6 +603,7 @@ public class TrustManagerService extends SystemService {
            if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(
                    intent.getAction())) {
                refreshAgentList();
                updateDevicePolicyFeatures(getSendingUserId());
            }
        }