| /* |
| * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| package sun.jkernel; |
| |
| import java.io.*; |
| |
| /** |
| * Invoked by DownloadManager to begin (in a new JRE) the process of downloading |
| * all remaining JRE components in the background. A mutex is used to ensure |
| * that only one BackgroundDownloader can be active at a time. |
| * |
| */ |
| public class BackgroundDownloader { |
| public static final String BACKGROUND_DOWNLOAD_PROPERTY = "kernel.background.download"; |
| // relative to the bundle directory |
| public static final String PID_PATH = "tmp" + File.separator + "background.pid"; |
| |
| // Time to wait before beginning to download components. Gives the JRE |
| // which spawned this one a chance to get its downloads going. |
| private static final int WAIT_TIME = 10000; |
| |
| private static Mutex backgroundMutex; |
| |
| static synchronized Mutex getBackgroundMutex() { |
| if (backgroundMutex == null) |
| backgroundMutex = Mutex.create(DownloadManager.MUTEX_PREFIX + "background"); |
| return backgroundMutex; |
| } |
| |
| private static void doBackgroundDownloads() { |
| if (DownloadManager.isJREComplete()) |
| return; |
| if (getBackgroundMutex().acquire(0)) { // give up and exit immediately if we can't acquire mutex |
| try { |
| writePid(); |
| Thread.sleep(WAIT_TIME); |
| DownloadManager.doBackgroundDownloads(false); |
| DownloadManager.performCompletionIfNeeded(); |
| } |
| catch (InterruptedException e) { |
| } |
| finally { |
| getBackgroundMutex().release(); |
| } |
| } |
| else { |
| System.err.println("Unable to acquire background download mutex."); |
| System.exit(1); |
| } |
| } |
| |
| |
| /** |
| * Writes the current process ID to a file, so that the uninstaller can |
| * find and kill this process if needed. |
| */ |
| private static void writePid() { |
| try { |
| File pid = new File(DownloadManager.getBundlePath(), PID_PATH); |
| pid.getParentFile().mkdirs(); |
| PrintStream out = new PrintStream(new FileOutputStream(pid)); |
| pid.deleteOnExit(); |
| out.println(DownloadManager.getCurrentProcessId()); |
| out.close(); |
| } |
| catch (IOException e) { |
| e.printStackTrace(); |
| System.exit(1); |
| } |
| } |
| |
| |
| /** |
| * Reads from an InputStream until exhausted, writing all data to the |
| * specified OutputStream. |
| */ |
| private static void send(InputStream in, OutputStream out) |
| throws IOException { |
| int c; |
| byte[] buffer = new byte[2048]; |
| while ((c = in.read(buffer)) > 0) |
| out.write(buffer, 0, c); |
| } |
| |
| /* |
| * Returns the value of the BACKGROUND_DOWNLOAD_PROPERTY. |
| * Checks if system property has been set first |
| * then checks if registry key to disable background download |
| * has been set. |
| */ |
| public static boolean getBackgroundDownloadProperty(){ |
| /* |
| * Check registry key value |
| */ |
| boolean bgDownloadEnabled = getBackgroundDownloadKey(); |
| |
| /* |
| * Check system property - it should override the registry |
| * key value. |
| */ |
| if (System.getProperty(BACKGROUND_DOWNLOAD_PROPERTY) != null){ |
| bgDownloadEnabled = Boolean.valueOf( |
| System.getProperty(BACKGROUND_DOWNLOAD_PROPERTY)); |
| } |
| return bgDownloadEnabled; |
| |
| } |
| |
| // This method is to retrieve the value of registry key |
| // that disables background download. |
| static native boolean getBackgroundDownloadKey(); |
| |
| |
| static void startBackgroundDownloads() { |
| if (!getBackgroundDownloadProperty()){ |
| // If getBackgroundDownloadProperty() returns false |
| // we're doing the downloads from this VM; we don't want to |
| // spawn another one |
| return; |
| } |
| |
| // if System.err isn't initialized yet, it means the charsets aren't |
| // available yet and we're going to run into trouble down below. Wait |
| // until it's ready. |
| while (System.err == null) { |
| try { |
| Thread.sleep(1000); |
| } |
| catch (InterruptedException e) { |
| return; |
| } |
| } |
| |
| try { |
| String args = "-D" + BACKGROUND_DOWNLOAD_PROPERTY + "=false -Xmx256m"; |
| String backgroundDownloadURL = DownloadManager.getBaseDownloadURL(); |
| |
| // only set KERNEL_DOWNLOAD_URL_PROPERTY if we override |
| // the default download url |
| if (backgroundDownloadURL != null && |
| backgroundDownloadURL.equals( |
| DownloadManager.DEFAULT_DOWNLOAD_URL) == false) { |
| args += " -D" + DownloadManager.KERNEL_DOWNLOAD_URL_PROPERTY + |
| "=" + backgroundDownloadURL; |
| }; |
| args += " sun.jkernel.BackgroundDownloader"; |
| final Process jvm = Runtime.getRuntime().exec("\"" + new File(System.getProperty("java.home"), "bin" + |
| File.separator + "java.exe") + "\" " + args); |
| Thread outputReader = new Thread("kernelOutputReader") { |
| public void run() { |
| try { |
| InputStream in = jvm.getInputStream(); |
| send(in, new PrintStream(new ByteArrayOutputStream())); |
| } |
| catch (IOException e) { |
| e.printStackTrace(); |
| } |
| } |
| }; |
| outputReader.setDaemon(true); |
| outputReader.start(); |
| |
| Thread errorReader = new Thread("kernelErrorReader") { |
| public void run() { |
| try { |
| InputStream in = jvm.getErrorStream(); |
| send(in, new PrintStream(new ByteArrayOutputStream())); |
| } |
| catch (IOException e) { |
| e.printStackTrace(); |
| } |
| } |
| }; |
| errorReader.setDaemon(true); |
| errorReader.start(); |
| } |
| catch (Exception e) { |
| e.printStackTrace(); |
| // TODO: error handling |
| } |
| } |
| |
| |
| public static void main(String[] arg) { |
| doBackgroundDownloads(); |
| } |
| } |