< prev index next >

src/java.desktop/share/classes/sun/awt/AppContext.java

Print this page


   1 /*
   2  * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 106  * }</pre><p>
 107  *
 108  * Since a separate AppContext can exist for each ThreadGroup, trusted
 109  * and untrusted code have access to different Foo instances.  This allows
 110  * untrusted code access to "system-wide" services -- the service remains
 111  * within the AppContext "sandbox".  For example, say a malicious applet
 112  * wants to peek all of the key events on the EventQueue to listen for
 113  * passwords; if separate EventQueues are used for each ThreadGroup
 114  * using AppContexts, the only key events that applet will be able to
 115  * listen to are its own.  A more reasonable applet request would be to
 116  * change the Swing default look-and-feel; with that default stored in
 117  * an AppContext, the applet's look-and-feel will change without
 118  * disrupting other applets or potentially the browser itself.<p>
 119  *
 120  * Because the AppContext is a facility for safely extending application
 121  * service support to applets, none of its methods may be blocked by a
 122  * a SecurityManager check in a valid Java implementation.  Applets may
 123  * therefore safely invoke any of its methods without worry of being
 124  * blocked.
 125  *
 126  * Note: If a SecurityManager is installed which derives from
 127  * sun.awt.AWTSecurityManager, it may override the
 128  * AWTSecurityManager.getAppContext() method to return the proper
 129  * AppContext based on the execution context, in the case where
 130  * the default ThreadGroup-based AppContext indexing would return
 131  * the main "system" AppContext.  For example, in an applet situation,
 132  * if a system thread calls into an applet, rather than returning the
 133  * main "system" AppContext (the one corresponding to the system thread),
 134  * an installed AWTSecurityManager may return the applet's AppContext
 135  * based on the execution context.
 136  *
 137  * @author  Thomas Ball
 138  * @author  Fred Ecks
 139  */
 140 public final class AppContext {
 141     private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.AppContext");
 142 
 143     /* Since the contents of an AppContext are unique to each Java
 144      * session, this class should never be serialized. */
 145 
 146     /*
 147      * The key to put()/get() the Java EventQueue into/from the AppContext.
 148      */
 149     public static final Object EVENT_QUEUE_KEY = new StringBuffer("EventQueue");
 150 
 151     /*
 152      * The keys to store EventQueue push/pop lock and condition.
 153      */
 154     public static final Object EVENT_QUEUE_LOCK_KEY = new StringBuilder("EventQueue.Lock");
 155     public static final Object EVENT_QUEUE_COND_KEY = new StringBuilder("EventQueue.Condition");
 156 


 270         // code is unaffected by the move to multiple AppContext ability.
 271         AccessController.doPrivileged(new PrivilegedAction<Void>() {
 272             public Void run() {
 273                 ThreadGroup currentThreadGroup =
 274                         Thread.currentThread().getThreadGroup();
 275                 ThreadGroup parentThreadGroup = currentThreadGroup.getParent();
 276                 while (parentThreadGroup != null) {
 277                     // Find the root ThreadGroup to construct our main AppContext
 278                     currentThreadGroup = parentThreadGroup;
 279                     parentThreadGroup = currentThreadGroup.getParent();
 280                 }
 281 
 282                 mainAppContext = SunToolkit.createNewAppContext(currentThreadGroup);
 283                 return null;
 284             }
 285         });
 286     }
 287 
 288     /**
 289      * Returns the appropriate AppContext for the caller,
 290      * as determined by its ThreadGroup.  If the main "system" AppContext
 291      * would be returned and there's an AWTSecurityManager installed, it
 292      * is called to get the proper AppContext based on the execution
 293      * context.
 294      *
 295      * @return  the AppContext for the caller.
 296      * @see     java.lang.ThreadGroup
 297      * @since   1.2
 298      */
 299     public static AppContext getAppContext() {
 300         // we are standalone app, return the main app context
 301         if (numAppContexts.get() == 1 && mainAppContext != null) {
 302             return mainAppContext;
 303         }
 304 
 305         AppContext appContext = threadAppContext.get();
 306 
 307         if (null == appContext) {
 308             appContext = AccessController.doPrivileged(new PrivilegedAction<AppContext>()
 309             {
 310                 public AppContext run() {
 311                     // Get the current ThreadGroup, and look for it and its
 312                     // parents in the hash from ThreadGroup to AppContext --
 313                     // it should be found, because we use createNewContext()


 367 
 368                     return context;
 369                 }
 370             });
 371         }
 372 
 373         return appContext;
 374     }
 375 
 376     /**
 377      * Returns true if the specified AppContext is the main AppContext.
 378      *
 379      * @param   ctx the context to compare with the main context
 380      * @return  true if the specified AppContext is the main AppContext.
 381      * @since   1.8
 382      */
 383     public static boolean isMainContext(AppContext ctx) {
 384         return (ctx != null && ctx == mainAppContext);
 385     }
 386 
 387     private static AppContext getExecutionAppContext() {
 388         SecurityManager securityManager = System.getSecurityManager();
 389         if ((securityManager != null) &&
 390             (securityManager instanceof AWTSecurityManager))
 391         {
 392             AWTSecurityManager awtSecMgr = (AWTSecurityManager) securityManager;
 393             AppContext secAppContext = awtSecMgr.getAppContext();
 394             return secAppContext; // Return what we're told
 395         }
 396         return null;
 397     }
 398 
 399     private long DISPOSAL_TIMEOUT = 5000;  // Default to 5-second timeout
 400                                            // for disposal of all Frames
 401                                            // (we wait for this time twice,
 402                                            // once for dispose(), and once
 403                                            // to clear the EventQueue).
 404 
 405     private long THREAD_INTERRUPT_TIMEOUT = 1000;
 406                             // Default to 1-second timeout for all
 407                             // interrupted Threads to exit, and another
 408                             // 1 second for all stopped Threads to die.
 409 
 410     /**
 411      * Disposes of this AppContext, all of its top-level Frames, and
 412      * all Threads and ThreadGroups contained within it.
 413      *
 414      * This method must be called from a Thread which is not contained
 415      * within this AppContext.
 416      *
 417      * @exception  IllegalThreadStateException  if the current thread is
 418      *                                    contained within this AppContext


 855                 });
 856             }
 857 
 858             /**
 859              * Returns the AppContext used for applet logging isolation, or null if
 860              * the default global context can be used.
 861              * If there's no applet, or if the caller is a stand alone application,
 862              * or running in the main app context, returns null.
 863              * Otherwise, returns the AppContext of the calling applet.
 864              * @return null if the global default context can be used,
 865              *         an AppContext otherwise.
 866              **/
 867             public Object getAppletContext() {
 868                 // There's no AppContext: return null.
 869                 // No need to call getAppContext() if numAppContext == 0:
 870                 // it means that no AppContext has been created yet, and
 871                 // we don't want to trigger the creation of a main app
 872                 // context since we don't need it.
 873                 if (numAppContexts.get() == 0) return null;
 874 
 875                 // Get the context from the security manager
 876                 AppContext ecx = getExecutionAppContext();
 877 
 878                 // Not sure we really need to re-check numAppContexts here.
 879                 // If all applets have gone away then we could have a
 880                 // numAppContexts coming back to 0. So we recheck
 881                 // it here because we don't want to trigger the
 882                 // creation of a main AppContext in that case.
 883                 // This is probably not 100% MT-safe but should reduce
 884                 // the window of opportunity in which that issue could
 885                 // happen.
 886                 if (numAppContexts.get() > 0) {
 887                     // Defaults to thread group caching.
 888                     // This is probably not required as we only really need
 889                     // isolation in a deployed applet environment, in which
 890                     // case ecx will not be null when we reach here
 891                     // However it helps emulate the deployed environment,
 892                     // in tests for instance.
 893                     ecx = ecx != null ? ecx : getAppContext();
 894                 }
 895 
 896                 // getAppletContext() may be called when initializing the main


   1 /*
   2  * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 106  * }</pre><p>
 107  *
 108  * Since a separate AppContext can exist for each ThreadGroup, trusted
 109  * and untrusted code have access to different Foo instances.  This allows
 110  * untrusted code access to "system-wide" services -- the service remains
 111  * within the AppContext "sandbox".  For example, say a malicious applet
 112  * wants to peek all of the key events on the EventQueue to listen for
 113  * passwords; if separate EventQueues are used for each ThreadGroup
 114  * using AppContexts, the only key events that applet will be able to
 115  * listen to are its own.  A more reasonable applet request would be to
 116  * change the Swing default look-and-feel; with that default stored in
 117  * an AppContext, the applet's look-and-feel will change without
 118  * disrupting other applets or potentially the browser itself.<p>
 119  *
 120  * Because the AppContext is a facility for safely extending application
 121  * service support to applets, none of its methods may be blocked by a
 122  * a SecurityManager check in a valid Java implementation.  Applets may
 123  * therefore safely invoke any of its methods without worry of being
 124  * blocked.
 125  *











 126  * @author  Thomas Ball
 127  * @author  Fred Ecks
 128  */
 129 public final class AppContext {
 130     private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.AppContext");
 131 
 132     /* Since the contents of an AppContext are unique to each Java
 133      * session, this class should never be serialized. */
 134 
 135     /*
 136      * The key to put()/get() the Java EventQueue into/from the AppContext.
 137      */
 138     public static final Object EVENT_QUEUE_KEY = new StringBuffer("EventQueue");
 139 
 140     /*
 141      * The keys to store EventQueue push/pop lock and condition.
 142      */
 143     public static final Object EVENT_QUEUE_LOCK_KEY = new StringBuilder("EventQueue.Lock");
 144     public static final Object EVENT_QUEUE_COND_KEY = new StringBuilder("EventQueue.Condition");
 145 


 259         // code is unaffected by the move to multiple AppContext ability.
 260         AccessController.doPrivileged(new PrivilegedAction<Void>() {
 261             public Void run() {
 262                 ThreadGroup currentThreadGroup =
 263                         Thread.currentThread().getThreadGroup();
 264                 ThreadGroup parentThreadGroup = currentThreadGroup.getParent();
 265                 while (parentThreadGroup != null) {
 266                     // Find the root ThreadGroup to construct our main AppContext
 267                     currentThreadGroup = parentThreadGroup;
 268                     parentThreadGroup = currentThreadGroup.getParent();
 269                 }
 270 
 271                 mainAppContext = SunToolkit.createNewAppContext(currentThreadGroup);
 272                 return null;
 273             }
 274         });
 275     }
 276 
 277     /**
 278      * Returns the appropriate AppContext for the caller,
 279      * as determined by its ThreadGroup.



 280      *
 281      * @return  the AppContext for the caller.
 282      * @see     java.lang.ThreadGroup
 283      * @since   1.2
 284      */
 285     public static AppContext getAppContext() {
 286         // we are standalone app, return the main app context
 287         if (numAppContexts.get() == 1 && mainAppContext != null) {
 288             return mainAppContext;
 289         }
 290 
 291         AppContext appContext = threadAppContext.get();
 292 
 293         if (null == appContext) {
 294             appContext = AccessController.doPrivileged(new PrivilegedAction<AppContext>()
 295             {
 296                 public AppContext run() {
 297                     // Get the current ThreadGroup, and look for it and its
 298                     // parents in the hash from ThreadGroup to AppContext --
 299                     // it should be found, because we use createNewContext()


 353 
 354                     return context;
 355                 }
 356             });
 357         }
 358 
 359         return appContext;
 360     }
 361 
 362     /**
 363      * Returns true if the specified AppContext is the main AppContext.
 364      *
 365      * @param   ctx the context to compare with the main context
 366      * @return  true if the specified AppContext is the main AppContext.
 367      * @since   1.8
 368      */
 369     public static boolean isMainContext(AppContext ctx) {
 370         return (ctx != null && ctx == mainAppContext);
 371     }
 372 












 373     private long DISPOSAL_TIMEOUT = 5000;  // Default to 5-second timeout
 374                                            // for disposal of all Frames
 375                                            // (we wait for this time twice,
 376                                            // once for dispose(), and once
 377                                            // to clear the EventQueue).
 378 
 379     private long THREAD_INTERRUPT_TIMEOUT = 1000;
 380                             // Default to 1-second timeout for all
 381                             // interrupted Threads to exit, and another
 382                             // 1 second for all stopped Threads to die.
 383 
 384     /**
 385      * Disposes of this AppContext, all of its top-level Frames, and
 386      * all Threads and ThreadGroups contained within it.
 387      *
 388      * This method must be called from a Thread which is not contained
 389      * within this AppContext.
 390      *
 391      * @exception  IllegalThreadStateException  if the current thread is
 392      *                                    contained within this AppContext


 829                 });
 830             }
 831 
 832             /**
 833              * Returns the AppContext used for applet logging isolation, or null if
 834              * the default global context can be used.
 835              * If there's no applet, or if the caller is a stand alone application,
 836              * or running in the main app context, returns null.
 837              * Otherwise, returns the AppContext of the calling applet.
 838              * @return null if the global default context can be used,
 839              *         an AppContext otherwise.
 840              **/
 841             public Object getAppletContext() {
 842                 // There's no AppContext: return null.
 843                 // No need to call getAppContext() if numAppContext == 0:
 844                 // it means that no AppContext has been created yet, and
 845                 // we don't want to trigger the creation of a main app
 846                 // context since we don't need it.
 847                 if (numAppContexts.get() == 0) return null;
 848 
 849                 AppContext ecx = null;

 850 
 851                 // Not sure we really need to re-check numAppContexts here.
 852                 // If all applets have gone away then we could have a
 853                 // numAppContexts coming back to 0. So we recheck
 854                 // it here because we don't want to trigger the
 855                 // creation of a main AppContext in that case.
 856                 // This is probably not 100% MT-safe but should reduce
 857                 // the window of opportunity in which that issue could
 858                 // happen.
 859                 if (numAppContexts.get() > 0) {
 860                     // Defaults to thread group caching.
 861                     // This is probably not required as we only really need
 862                     // isolation in a deployed applet environment, in which
 863                     // case ecx will not be null when we reach here
 864                     // However it helps emulate the deployed environment,
 865                     // in tests for instance.
 866                     ecx = ecx != null ? ecx : getAppContext();
 867                 }
 868 
 869                 // getAppletContext() may be called when initializing the main


< prev index next >