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

Commit c7639333 authored by Jim Miller's avatar Jim Miller Committed by Android (Google) Code Review
Browse files

Merge "Update TrustAgentService API after review." into lmp-dev

parents ed402566 d4efaac5
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1373,6 +1373,8 @@ public class DevicePolicyManager {
     * and its profiles or a particular one.
     * @param admin The name of the admin component to check, or null to aggregate
     * all admins.
     * @return time in milliseconds for the given admin or the minimum value (strictest) of
     * all admins if admin is null.
     */
    public long getMaximumTimeToLock(ComponentName admin) {
        return getMaximumTimeToLock(admin, UserHandle.myUserId());
+1 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.service.trust.ITrustAgentServiceCallback;
 */
interface ITrustAgentService {
    oneway void onUnlockAttempt(boolean successful);
    oneway void onTrustTimeout();
    oneway void setCallback(ITrustAgentServiceCallback callback);
    oneway void setTrustAgentFeaturesEnabled(in Bundle options, IBinder token);
}
+46 −14
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.Log;
import android.util.Slog;

@@ -37,7 +38,10 @@ import android.util.Slog;
 * A service that notifies the system about whether it believes the environment of the device
 * to be trusted.
 *
 * <p>Trust agents may only be provided by the platform.</p>
 * <p>Trust agents may only be provided by the platform. It is expected that there is only
 * one trust agent installed on the platform. In the event there is more than one,
 * either trust agent can enable trust.
 * </p>
 *
 * <p>To extend this class, you must declare the service in your manifest file with
 * the {@link android.Manifest.permission#BIND_TRUST_AGENT} permission
@@ -90,6 +94,7 @@ public class TrustAgentService extends Service {

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

    private ITrustAgentServiceCallback mCallback;

@@ -118,6 +123,9 @@ public class TrustAgentService extends Service {
                        onError("calling onSetTrustAgentFeaturesEnabledCompleted()");
                    }
                    break;
                case MSG_TRUST_TIMEOUT:
                    onTrustTimeout();
                    break;
            }
        }
    };
@@ -139,21 +147,32 @@ public class TrustAgentService extends Service {
    }

    /**
     * Called when the user attempted to authenticate on the device.
     * Called after the user attempts to authenticate in keyguard with their device credentials,
     * such as pin, pattern or password.
     *
     * @param successful true if the attempt succeeded
     * @param successful true if the user successfully completed the challenge.
     */
    public void onUnlockAttempt(boolean successful) {
    }

    /**
     * Called when the timeout provided by the agent expires.  Note that this may be called earlier
     * than requested by the agent if the trust timeout is adjusted by the system or
     * {@link DevicePolicyManager}.  The agent is expected to re-evaluate the trust state and only
     * call {@link #grantTrust(CharSequence, long, boolean)} if the trust state should be
     * continued.
     */
    public void onTrustTimeout() {
    }

    private void onError(String msg) {
        Slog.v(TAG, "Remote exception while " + msg);
    }

    /**
     * Called when device policy wants to restrict features in the TrustAgent in response to
     * Called when device policy wants to restrict features in the agent in response to
     * {@link DevicePolicyManager#setTrustAgentFeaturesEnabled(ComponentName, ComponentName, java.util.List) }.
     * TrustAgents that support this feature should overload this method and return 'true'.
     * Agents that support this feature should overload this method and return 'true'.
     *
     * The list of options can be obtained by calling
     * options.getStringArrayList({@link #KEY_FEATURES}). Presence of a feature string in the list
@@ -174,10 +193,19 @@ public class TrustAgentService extends Service {
     * Call to grant trust on the device.
     *
     * @param message describes why the device is trusted, e.g. "Trusted by location".
     * @param durationMs amount of time in milliseconds to keep the device in a trusted state. Trust
     *                   for this agent will automatically be revoked when the timeout expires.
     * @param initiatedByUser indicates that the user has explicitly initiated an action that proves
     *                        the user is about to use the device.
     * @param durationMs amount of time in milliseconds to keep the device in a trusted state.
     *    Trust for this agent will automatically be revoked when the timeout expires unless
     *    extended by a subsequent call to this function. The timeout is measured from the
     *    invocation of this function as dictated by {@link SystemClock#elapsedRealtime())}.
     *    For security reasons, the value should be no larger than necessary.
     *    The value may be adjusted by the system as necessary to comply with a policy controlled
     *    by the system or {@link DevicePolicyManager} restrictions. See {@link #onTrustTimeout()}
     *    for determining when trust expires.
     * @param initiatedByUser this is a hint to the system that trust is being granted as the
     *    direct result of user action - such as solving a security challenge. The hint is used
     *    by the system to optimize the experience. Behavior may vary by device and release, so
     *    one should only set this parameter if it meets the above criteria rather than relying on
     *    the behavior of any particular device or release.
     * @throws IllegalStateException if the agent is not currently managing trust.
     */
    public final void grantTrust(
@@ -254,13 +282,17 @@ public class TrustAgentService extends Service {
    }

    private final class TrustAgentServiceWrapper extends ITrustAgentService.Stub {
        @Override
        @Override /* Binder API */
        public void onUnlockAttempt(boolean successful) {
            mHandler.obtainMessage(MSG_UNLOCK_ATTEMPT, successful ? 1 : 0, 0)
                    .sendToTarget();
            mHandler.obtainMessage(MSG_UNLOCK_ATTEMPT, successful ? 1 : 0, 0).sendToTarget();
        }

        @Override
        @Override /* Binder API */
        public void onTrustTimeout() {
            mHandler.sendEmptyMessage(MSG_TRUST_TIMEOUT);
        }

        @Override /* Binder API */
        public void setCallback(ITrustAgentServiceCallback callback) {
            synchronized (mLock) {
                mCallback = callback;
@@ -280,7 +312,7 @@ public class TrustAgentService extends Service {
            }
        }

        @Override
        @Override /* Binder API */
        public void setTrustAgentFeaturesEnabled(Bundle features, IBinder token) {
            Message msg = mHandler.obtainMessage(MSG_SET_TRUST_AGENT_FEATURES_ENABLED, token);
            msg.setData(features);
+6 −0
Original line number Diff line number Diff line
@@ -75,6 +75,12 @@ public class SampleTrustAgent extends TrustAgentService
                .registerOnSharedPreferenceChangeListener(this);
    }

    @Override
    public void onTrustTimeout() {
        super.onTrustTimeout();
        Toast.makeText(this, "onTrustTimeout(): timeout expired", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onUnlockAttempt(boolean successful) {
        if (getReportUnlockAttempts(this)) {
+46 −2
Original line number Diff line number Diff line
@@ -16,16 +16,22 @@

package com.android.server.trust;

import android.app.AlarmManager;
import android.app.PendingIntent;
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.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.PatternMatcher;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
@@ -43,6 +49,9 @@ import java.util.List;
 * TrustManager and the actual TrustAgent.
 */
public class TrustAgentWrapper {
    private static final String EXTRA_COMPONENT_NAME = "componentName";
    private static final String TRUST_EXPIRED_ACTION = "android.server.trust.TRUST_EXPIRED_ACTION";
    private static final String PERMISSION = "android.permission.PROVIDE_TRUST_AGENT";
    private static final boolean DEBUG = false;
    private static final String TAG = "TrustAgentWrapper";

@@ -79,6 +88,20 @@ public class TrustAgentWrapper {
    private boolean mTrustDisabledByDpm;
    private boolean mManagingTrust;
    private IBinder mSetTrustAgentFeaturesToken;
    private AlarmManager mAlarmManager;
    private final Intent mAlarmIntent;

    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            ComponentName component = intent.getParcelableExtra(EXTRA_COMPONENT_NAME);
            if (TRUST_EXPIRED_ACTION.equals(intent.getAction())
                    && mName.equals(component)) {
                mHandler.removeMessages(MSG_TRUST_TIMEOUT);
                mHandler.sendEmptyMessage(MSG_TRUST_TIMEOUT);
            }
        }
    };

    private final Handler mHandler = new Handler() {
        @Override
@@ -95,8 +118,10 @@ public class TrustAgentWrapper {
                    boolean initiatedByUser = msg.arg1 != 0;
                    long durationMs = msg.getData().getLong(DATA_DURATION);
                    if (durationMs > 0) {
                        mHandler.removeMessages(MSG_TRUST_TIMEOUT);
                        mHandler.sendEmptyMessageDelayed(MSG_TRUST_TIMEOUT, durationMs);
                        long expiration = SystemClock.elapsedRealtime() + durationMs;
                        PendingIntent op = PendingIntent.getBroadcast(mContext, 0, mAlarmIntent,
                                PendingIntent.FLAG_CANCEL_CURRENT);
                        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, expiration, op);
                    }
                    mTrustManagerService.mArchive.logGrantTrust(mUserId, mName,
                            (mMessage != null ? mMessage.toString() : null),
@@ -106,6 +131,7 @@ public class TrustAgentWrapper {
                case MSG_TRUST_TIMEOUT:
                    if (DEBUG) Slog.v(TAG, "Trust timed out : " + mName.flattenToShortString());
                    mTrustManagerService.mArchive.logTrustTimeout(mUserId, mName);
                    onTrustTimeout();
                    // Fall through.
                case MSG_REVOKE_TRUST:
                    mTrusted = false;
@@ -212,8 +238,19 @@ public class TrustAgentWrapper {
            Intent intent, UserHandle user) {
        mContext = context;
        mTrustManagerService = trustManagerService;
        mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
        mUserId = user.getIdentifier();
        mName = intent.getComponent();

        mAlarmIntent = new Intent(TRUST_EXPIRED_ACTION).putExtra(EXTRA_COMPONENT_NAME, mName);
        mAlarmIntent.setData(Uri.parse(mAlarmIntent.toUri(Intent.URI_INTENT_SCHEME)));

        final IntentFilter alarmFilter = new IntentFilter(TRUST_EXPIRED_ACTION);
        alarmFilter.addDataScheme(mAlarmIntent.getScheme());
        final String pathUri = mAlarmIntent.toUri(Intent.URI_INTENT_SCHEME);
        alarmFilter.addDataPath(pathUri, PatternMatcher.PATTERN_LITERAL);
        mContext.registerReceiver(mBroadcastReceiver, alarmFilter);

        // Schedules a restart for when connecting times out. If the connection succeeds,
        // the restart is canceled in mCallback's onConnected.
        scheduleRestart();
@@ -227,6 +264,13 @@ public class TrustAgentWrapper {
        Slog.w(TAG , "Remote Exception", e);
    }

    private void onTrustTimeout() {
        try {
            if (mTrustAgentService != null) mTrustAgentService.onTrustTimeout();
        } catch (RemoteException e) {
            onError(e);
        }
    }
    /**
     * @see android.service.trust.TrustAgentService#onUnlockAttempt(boolean)
     */