FileDocCategorySizeDatePackage
AccessController.javaAPI DocAndroid 1.5 API15689Wed May 06 22:41:04 BST 2009java.security

AccessController

public final class AccessController extends Object
{@code AccessController} provides static methods to perform access control checks and privileged operations.

Fields Summary
private static final WeakHashMap
contexts
A map used to store a mapping between a given Thread and AccessControllerContext-s used in successive calls of doPrivileged(). A WeakHashMap is used to allow automagical wiping of the dead threads from the map. The thread (normally Thread.currentThread()) is used as a key for the map, and a value is ArrayList where all AccessControlContext-s are stored. ((ArrayList)contexts.get(Thread.currentThread())).lastElement() - is reference to the latest context passed to the doPrivileged() call.
Constructors Summary
private AccessController()

        throw new Error("statics only.");
    
Methods Summary
public static voidcheckPermission(java.security.Permission perm)
Checks the specified permission against the vm's current security policy. The check is performed in the context of the current thread. This method returns silently if the permission is granted, otherwise an {@code AccessControlException} is thrown.

A permission is considered granted if every {@link ProtectionDomain} in the current execution context has been granted the specified permission. If privileged operations are on the execution context, only the {@code ProtectionDomain}s from the last privileged operation are taken into account.

This method delegates the permission check to {@link AccessControlContext#checkPermission(Permission)} on the current callers' context obtained by {@link #getContext()}.

param
perm the permission to check against the policy
throws
AccessControlException if the specified permission is not granted
throws
NullPointerException if the specified permission is {@code null}
see
AccessControlContext#checkPermission(Permission)
since
Android 1.0

        if (perm == null) {
            throw new NullPointerException("permission can not be null");
        }

        getContext().checkPermission(perm);
    
public static TdoPrivileged(java.security.PrivilegedAction action)
Returns the result of executing the specified privileged action. Only the {@code ProtectionDomain} of the direct caller of this method and the {@code ProtectionDomain}s of all subsequent classes in the call chain are checked to be granted the necessary permission if access checks are performed.

If an instance of {@code RuntimeException} is thrown during the execution of the {@code PrivilegedAction#run()} method of the given action, it will be propagated through this method.

param
action the action to be executed with privileges
return
the result of executing the privileged action
throws
NullPointerException if the specified action is {@code null}
since
Android 1.0


                                                                                                                                       
          
        if (action == null) {
            throw new NullPointerException("action can not be null");
        }
        return doPrivilegedImpl(action, null);
    
public static TdoPrivileged(java.security.PrivilegedAction action, java.security.AccessControlContext context)
Returns the result of executing the specified privileged action. The {@code ProtectionDomain} of the direct caller of this method, the {@code ProtectionDomain}s of all subsequent classes in the call chain and all {@code ProtectionDomain}s of the given context are checked to be granted the necessary permission if access checks are performed.

If an instance of {@code RuntimeException} is thrown during the execution of the {@code PrivilegedAction#run()} method of the given action, it will be propagated through this method.

param
action the action to be executed with privileges
param
context the {@code AccessControlContext} whose protection domains are checked additionally
return
the result of executing the privileged action
throws
NullPointerException if the specified action is {@code null}
since
Android 1.0

        if (action == null) {
            throw new NullPointerException("action can not be null");
        }
        return doPrivilegedImpl(action, context);
    
public static TdoPrivileged(java.security.PrivilegedExceptionAction action)
Returns the result of executing the specified privileged action. Only the {@code ProtectionDomain} of the direct caller of this method and the {@code ProtectionDomain}s of all subsequent classes in the call chain are checked to be granted the necessary permission if access checks are performed.

If a checked exception is thrown by the action's run method, it will be wrapped and propagated through this method.

If an instance of {@code RuntimeException} is thrown during the execution of the {@code PrivilegedAction#run()} method of the given action, it will be propagated through this method.

param
action the action to be executed with privileges
return
the result of executing the privileged action
throws
PrivilegedActionException if the action's run method throws any checked exception
throws
NullPointerException if the specified action is {@code null}
since
Android 1.0

        if (action == null) {
            throw new NullPointerException("action can not be null");
        }
        return doPrivilegedImpl(action, null);
    
public static TdoPrivileged(java.security.PrivilegedExceptionAction action, java.security.AccessControlContext context)
Returns the result of executing the specified privileged action. The {@code ProtectionDomain} of the direct caller of this method, the {@code ProtectionDomain}s of all subsequent classes in the call chain and all {@code ProtectionDomain}s of the given context are checked to be granted the necessary permission if access checks are performed.

If a checked exception is thrown by the action's run method, it will be wrapped and propagated through this method.

If an instance of {@code RuntimeException} is thrown during the execution of the {@code PrivilegedAction#run()} method of the given action, it will be propagated through this method.

param
action the action to be executed with privileges
param
context the {@code AccessControlContext} whose protection domains are checked additionally
return
the result of executing the privileged action
throws
PrivilegedActionException if the action's run method throws any checked exception
throws
NullPointerException if the specified action is {@code null}
since
Android 1.0

        if (action == null) {
            throw new NullPointerException("action can not be null");
        }
        return doPrivilegedImpl(action, context);
    
private static TdoPrivilegedImpl(java.security.PrivilegedExceptionAction action, java.security.AccessControlContext context)
The real implementation of doPrivileged() method. It pushes the passed context into this thread's contexts stack, and then invokes action.run(). The pushed context is then investigated in the {@link #getContext()} which is called in the {@link #checkPermission}.


        Thread currThread = Thread.currentThread();

        ArrayList<AccessControlContext> a = null;
        try {
            // currThread==null means that VM warm up is in progress
            if (currThread != null && contexts != null) {
                synchronized (contexts) {
                    a = contexts.get(currThread);
                    if (a == null) {
                        a = new ArrayList<AccessControlContext>();
                        contexts.put(currThread, a);
                    }
                }
                a.add(context);
            }
            return action.run();

        } catch (Exception ex) {
            // Errors automagically go through - they are not catched by this
            // block

            // Unchecked exceptions must pass through without modification
            if (ex instanceof RuntimeException) {
                throw (RuntimeException) ex;
            }

            // All other (==checked) exceptions get wrapped
            throw new PrivilegedActionException(ex);
        } finally {
            if (currThread != null) {
                // No need to sync() here, as each given 'a' will be accessed
                // only from one Thread. 'contexts' still need sync() however,
                // as it's accessed from different threads simultaneously
                if (a != null) {
                    // it seems I will never have here [v.size() == 0]
                    a.remove(a.size() - 1);
                }
            }
        }
    
private static TdoPrivilegedImpl(java.security.PrivilegedAction action, java.security.AccessControlContext context)
The real implementation of appropriate doPrivileged() method.
It pushes the passed context into this thread's stack of contexts and then invokes action.run().
The pushed context is then investigated in the {@link #getContext()} which is called in the {@link #checkPermission}.


        Thread currThread = Thread.currentThread();

        if (currThread == null || contexts == null) {
            // Big boom time - VM is starting... No need to check permissions:
            // 1st, I do believe there is no malicious code available here for
            // this moment
            // 2d, I cant use currentThread() as a key anyway - when it will
            // turn into the real Thread, I'll be unable to retrieve the value
            // stored with 'currThread==null' as a key.
            return action.run();
        }

        ArrayList<AccessControlContext> a = null;
        try {
            synchronized (contexts) {
                a = contexts.get(currThread);
                if (a == null) {
                    a = new ArrayList<AccessControlContext>();
                    contexts.put(currThread, a);
                }
            }
            a.add(context);

            return action.run();

        } finally {
            // No need to sync() here, as each given 'a' will be accessed
            // only from one Thread. 'contexts' still need sync() however,
            // as it's accessed from different threads simultaneously
            if (a != null) {
                a.remove(a.size() - 1);
            }
        }
    
public static java.security.AccessControlContextgetContext()
Returns the {@code AccessControlContext} for the current {@code Thread} including the inherited access control context of the thread that spawned the current thread (recursively).

The returned context may be used to perform access checks at a later point in time, possibly by another thread.

return
the {@code AccessControlContext} for the current {@code Thread}
see
Thread#currentThread
since
Android 1.0


        // duplicates (if any) will be removed in ACC constructor
        ProtectionDomain[] stack = getStackDomains();

        Thread currThread = Thread.currentThread();
        if (currThread == null || contexts == null) {
            // Big boo time. No need to check anything ?
            return new AccessControlContext(stack);
        }

        ArrayList<AccessControlContext> threadContexts;
        synchronized (contexts) {
            threadContexts = contexts.get(currThread);
        }

        AccessControlContext that;
        if ((threadContexts == null) || (threadContexts.size() == 0)) {
            // We were not in doPrivileged method, so
            // have inherited context here
            that = SecurityUtils.getContext(currThread);
        } else {
            // We were in doPrivileged method, so
            // Use context passed to the doPrivileged()
            that = threadContexts.get(threadContexts.size() - 1);
        }

        if (that != null && that.combiner != null) {
            ProtectionDomain[] assigned = null;
            if (that.context != null && that.context.length != 0) {
                assigned = new ProtectionDomain[that.context.length];
                System.arraycopy(that.context, 0, assigned, 0, assigned.length);
            }
            ProtectionDomain[] allpds = that.combiner.combine(stack, assigned);
            if (allpds == null) {
                allpds = new ProtectionDomain[0];
            }
            return new AccessControlContext(allpds, that.combiner);
        }

        return new AccessControlContext(stack, that);
    
private static native java.security.ProtectionDomain[]getStackDomains()
Returns array of ProtectionDomains from the classes residing on the stack of the current thread, up to and including the caller of the nearest privileged frame. Reflection frames are skipped. The returned array is never null and never contains null elements, meaning that bootstrap classes are effectively ignored.