Save This Page
Home » openjdk-7 » com.sun.media » sound » [javadoc | source]
    1   /*
    2    * Copyright (c) 1999, 2009, 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
   23    * questions.
   24    */
   25   
   26   package com.sun.media.sound;
   27   
   28   import java.io.BufferedInputStream;
   29   import java.io.InputStream;
   30   import java.io.File;
   31   import java.io.FileInputStream;
   32   
   33   import java.util.ArrayList;
   34   import java.util.Iterator;
   35   import java.util.List;
   36   import java.util.Properties;
   37   
   38   import java.security.AccessController;
   39   import java.security.PrivilegedAction;
   40   
   41   import javax.sound.sampled.AudioPermission;
   42   
   43   import sun.misc.Service;
   44   
   45   
   46   /** Managing security in the Java Sound implementation.
   47    * This class contains all code that uses and is used by
   48    * SecurityManager.doPrivileged().
   49    *
   50    * @author Matthias Pfisterer
   51    */
   52   class JSSecurityManager {
   53   
   54       /** Prevent instantiation.
   55        */
   56       private JSSecurityManager() {
   57       }
   58   
   59       /** Checks if the VM currently has a SecurityManager installed.
   60        * Note that this may change over time. So the result of this method
   61        * should not be cached.
   62        *
   63        * @return true if a SecurityManger is installed, false otherwise.
   64        */
   65       private static boolean hasSecurityManager() {
   66           return (System.getSecurityManager() != null);
   67       }
   68   
   69   
   70       static void checkRecordPermission() throws SecurityException {
   71           if(Printer.trace) Printer.trace("JSSecurityManager.checkRecordPermission()");
   72           SecurityManager sm = System.getSecurityManager();
   73           if (sm != null) {
   74               sm.checkPermission(new AudioPermission("record"));
   75           }
   76       }
   77   
   78   
   79       static void loadLibrary(final String libName) {
   80           try {
   81               if (hasSecurityManager()) {
   82                   if(Printer.debug) Printer.debug("using security manager to load library");
   83                   PrivilegedAction action = new PrivilegedAction() {
   84                           public Object run() {
   85                               System.loadLibrary(libName);
   86                               return null;
   87                           }
   88                       };
   89                   AccessController.doPrivileged(action);
   90               } else {
   91                   if(Printer.debug) Printer.debug("not using security manager to load library");
   92                   System.loadLibrary(libName);
   93               }
   94               if (Printer.debug) Printer.debug("loaded library " + libName);
   95           } catch (UnsatisfiedLinkError e2) {
   96               if (Printer.err)Printer.err("UnsatisfiedLinkError loading native library " + libName);
   97               throw(e2);
   98           }
   99       }
  100   
  101   
  102       static String getProperty(final String propertyName) {
  103           String propertyValue;
  104           if (hasSecurityManager()) {
  105               if(Printer.debug) Printer.debug("using JDK 1.2 security to get property");
  106               try{
  107                   PrivilegedAction action = new PrivilegedAction() {
  108                           public Object run() {
  109                               try {
  110                                   return System.getProperty(propertyName);
  111                               } catch (Throwable t) {
  112                                   return null;
  113                               }
  114                           }
  115                       };
  116                   propertyValue = (String) AccessController.doPrivileged(action);
  117               } catch( Exception e ) {
  118                   if(Printer.debug) Printer.debug("not using JDK 1.2 security to get properties");
  119                   propertyValue = System.getProperty(propertyName);
  120               }
  121           } else {
  122               if(Printer.debug) Printer.debug("not using JDK 1.2 security to get properties");
  123               propertyValue = System.getProperty(propertyName);
  124           }
  125           return propertyValue;
  126       }
  127   
  128   
  129       /** Load properties from a file.
  130           This method tries to load properties from the filename give into
  131           the passed properties object.
  132           If the file cannot be found or something else goes wrong,
  133           the method silently fails.
  134           @param properties The properties bundle to store the values of the
  135           properties file.
  136           @param filename The filename of the properties file to load. This
  137           filename is interpreted as relative to the subdirectory "lib" in
  138           the JRE directory.
  139        */
  140       static void loadProperties(final Properties properties,
  141                                  final String filename) {
  142           if(hasSecurityManager()) {
  143               try {
  144                   // invoke the privileged action using 1.2 security
  145                   PrivilegedAction action = new PrivilegedAction() {
  146                           public Object run() {
  147                               loadPropertiesImpl(properties, filename);
  148                               return null;
  149                           }
  150                       };
  151                   AccessController.doPrivileged(action);
  152                   if(Printer.debug)Printer.debug("Loaded properties with JDK 1.2 security");
  153               } catch (Exception e) {
  154                   if(Printer.debug)Printer.debug("Exception loading properties with JDK 1.2 security");
  155                   // try without using JDK 1.2 security
  156                   loadPropertiesImpl(properties, filename);
  157               }
  158           } else {
  159               // not JDK 1.2 security, assume we already have permission
  160               loadPropertiesImpl(properties, filename);
  161           }
  162       }
  163   
  164   
  165       private static void loadPropertiesImpl(Properties properties,
  166                                              String filename) {
  167           if(Printer.trace)Printer.trace(">> JSSecurityManager: loadPropertiesImpl()");
  168           String fname = System.getProperty("java.home");
  169           try {
  170               if (fname == null) {
  171                   throw new Error("Can't find java.home ??");
  172               }
  173               File f = new File(fname, "lib");
  174               f = new File(f, filename);
  175               fname = f.getCanonicalPath();
  176               InputStream in = new FileInputStream(fname);
  177               BufferedInputStream bin = new BufferedInputStream(in);
  178               try {
  179                   properties.load(bin);
  180               } finally {
  181                   if (in != null) {
  182                       in.close();
  183                   }
  184               }
  185           } catch (Throwable t) {
  186               if (Printer.trace) {
  187                   System.err.println("Could not load properties file \"" + fname + "\"");
  188                   t.printStackTrace();
  189               }
  190           }
  191           if(Printer.trace)Printer.trace("<< JSSecurityManager: loadPropertiesImpl() completed");
  192       }
  193   
  194   
  195       private static ThreadGroup getTopmostThreadGroup() {
  196           ThreadGroup topmostThreadGroup;
  197           if(hasSecurityManager()) {
  198               try {
  199                   // invoke the privileged action using 1.2 security
  200                   PrivilegedAction action = new PrivilegedAction() {
  201                           public Object run() {
  202                               try {
  203                                   return getTopmostThreadGroupImpl();
  204                               } catch (Throwable t) {
  205                                   return null;
  206                               }
  207                           }
  208                       };
  209                   topmostThreadGroup = (ThreadGroup) AccessController.doPrivileged(action);
  210                   if(Printer.debug)Printer.debug("Got topmost thread group with JDK 1.2 security");
  211               } catch (Exception e) {
  212                   if(Printer.debug)Printer.debug("Exception getting topmost thread group with JDK 1.2 security");
  213                   // try without using JDK 1.2 security
  214                   topmostThreadGroup = getTopmostThreadGroupImpl();
  215               }
  216           } else {
  217               // not JDK 1.2 security, assume we already have permission
  218               topmostThreadGroup = getTopmostThreadGroupImpl();
  219           }
  220           return topmostThreadGroup;
  221       }
  222   
  223   
  224       private static ThreadGroup getTopmostThreadGroupImpl() {
  225           if(Printer.trace)Printer.trace(">> JSSecurityManager: getTopmostThreadGroupImpl()");
  226           ThreadGroup g = Thread.currentThread().getThreadGroup();
  227           while ((g.getParent() != null) && (g.getParent().getParent() != null)) {
  228               g = g.getParent();
  229           }
  230           if(Printer.trace)Printer.trace("<< JSSecurityManager: getTopmostThreadGroupImpl() completed");
  231           return g;
  232       }
  233   
  234   
  235       /** Create a Thread in the topmost ThreadGroup.
  236        */
  237       static Thread createThread(final Runnable runnable,
  238                                  final String threadName,
  239                                  final boolean isDaemon, final int priority,
  240                                  final boolean doStart) {
  241           Thread thread = null;
  242           if(hasSecurityManager()) {
  243               PrivilegedAction action = new PrivilegedAction() {
  244                       public Object run() {
  245                           try {
  246                               return createThreadImpl(runnable, threadName,
  247                                                       isDaemon, priority,
  248                                                       doStart);
  249                           } catch (Throwable t) {
  250                               return null;
  251                           }
  252                       }
  253                   };
  254               thread = (Thread) AccessController.doPrivileged(action);
  255               if(Printer.debug) Printer.debug("created thread with JDK 1.2 security");
  256           } else {
  257               if(Printer.debug)Printer.debug("not using JDK 1.2 security");
  258               thread = createThreadImpl(runnable, threadName, isDaemon, priority,
  259                                         doStart);
  260           }
  261           return thread;
  262       }
  263   
  264   
  265       private static Thread createThreadImpl(Runnable runnable,
  266                                              String threadName,
  267                                              boolean isDaemon, int priority,
  268                                              boolean doStart) {
  269           ThreadGroup threadGroup = getTopmostThreadGroupImpl();
  270           Thread thread = new Thread(threadGroup, runnable);
  271           if (threadName != null) {
  272               thread.setName(threadName);
  273           }
  274           thread.setDaemon(isDaemon);
  275           if (priority >= 0) {
  276               thread.setPriority(priority);
  277           }
  278           if (doStart) {
  279               thread.start();
  280           }
  281           return thread;
  282       }
  283   
  284   
  285       static List getProviders(final Class providerClass) {
  286           List p = new ArrayList();
  287           // Service.providers(Class) just creates "lazy" iterator instance,
  288           // so it doesn't require do be called from privileged section
  289           final Iterator ps = Service.providers(providerClass);
  290   
  291           // the iterator's hasNext() method looks through classpath for
  292           // the provider class names, so it requires read permissions
  293           PrivilegedAction<Boolean> hasNextAction = new PrivilegedAction<Boolean>() {
  294               public Boolean run() {
  295                   return ps.hasNext();
  296               }
  297           };
  298   
  299           while (AccessController.doPrivileged(hasNextAction)) {
  300               try {
  301                   // the iterator's next() method creates instances of the
  302                   // providers and it should be called in the current security
  303                   // context
  304                   Object provider = ps.next();
  305                   if (providerClass.isInstance(provider)) {
  306                       // $$mp 2003-08-22
  307                       // Always adding at the beginning reverses the
  308                       // order of the providers. So we no longer have
  309                       // to do this in AudioSystem and MidiSystem.
  310                       p.add(0, provider);
  311                   }
  312               } catch (Throwable t) {
  313                   //$$fb 2002-11-07: do not fail on SPI not found
  314                   if (Printer.err) t.printStackTrace();
  315               }
  316           }
  317           return p;
  318       }
  319   }

Save This Page
Home » openjdk-7 » com.sun.media » sound » [javadoc | source]