javamanager/javainstaller/installer/javasrc/com/nokia/mj/impl/installer/midp2/install/steps/FinalizeInstallation.java
branchRCL_3
changeset 19 04becd199f91
child 35 85266cc22c7f
child 60 6c158198356e
equal deleted inserted replaced
16:f5050f1da672 19:04becd199f91
       
     1 /*
       
     2 * Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 package com.nokia.mj.impl.installer.midp2.install.steps;
       
    20 
       
    21 import com.nokia.mj.impl.installer.ui.ApplicationInfo;
       
    22 import com.nokia.mj.impl.installer.ui.LaunchAppInfo;
       
    23 import com.nokia.mj.impl.installer.applicationregistrator.ApplicationRegistrator;
       
    24 import com.nokia.mj.impl.installer.captainservice.CaptainService;
       
    25 import com.nokia.mj.impl.installer.exetable.ExeBall;
       
    26 import com.nokia.mj.impl.installer.exetable.ExeStep;
       
    27 import com.nokia.mj.impl.installer.Installer;
       
    28 import com.nokia.mj.impl.installer.utils.FileUtils;
       
    29 import com.nokia.mj.impl.installer.utils.InstallerException;
       
    30 import com.nokia.mj.impl.installer.utils.Log;
       
    31 import com.nokia.mj.impl.installer.utils.Platform;
       
    32 import com.nokia.mj.impl.utils.Uid;
       
    33 
       
    34 import java.io.InputStream;
       
    35 import java.io.IOException;
       
    36 import java.util.Vector;
       
    37 import java.util.jar.JarFile;
       
    38 import java.util.jar.JarEntry;
       
    39 
       
    40 public class FinalizeInstallation extends ExeStep
       
    41 {
       
    42     // JarFile instance, used for getting icon InputStreams.
       
    43     private JarFile iJarFile = null;
       
    44 
       
    45     public void execute(ExeBall aBall)
       
    46     {
       
    47         InstallBall ball = (InstallBall)aBall;
       
    48         ball.log("Finalizing installation...");
       
    49 
       
    50         // If posting OTA status notifications is still going on,
       
    51         // stop it now and continue when next installation is made.
       
    52         ball.getNotificationPoster().stop();
       
    53 
       
    54         // Cleanup security components.
       
    55         ball.cleanupSecurity();
       
    56 
       
    57         // If -forcecancel option was specified, abort execution
       
    58         // before committing anything.
       
    59         if (ball.iArgs.get("forcecancel") != null)
       
    60         {
       
    61             InstallerException.internalError("FORCED CANCEL");
       
    62         }
       
    63 
       
    64         // User is not allowed to cancel installation after this step.
       
    65         ball.setCanCancel(false);
       
    66 
       
    67         checkWaitAttribute(ball, "before storage commit");
       
    68 
       
    69         // StorageHandler must be committed before ApplicationRegistrator
       
    70         // so that platform specific application registry can use the data
       
    71         // in Java Storage (S60 AppArc application list re-scan)
       
    72         ball.iStorageHandler.commitSession();
       
    73 
       
    74         // StorageHandler commit is asynchronous. In case of
       
    75         // conversion installation or preinstallation wait for
       
    76         // a while so that the commit can be done before the
       
    77         // application registrator commit causes accesses to
       
    78         // Storage (S60 AppArc application list re-scan)
       
    79         if (ball.iConversionInstallation ||
       
    80                 ball.iPreinstallation)
       
    81         {
       
    82             try
       
    83             {
       
    84                 Thread.sleep(1000);
       
    85             }
       
    86             catch (InterruptedException ie)
       
    87                 { }
       
    88         }
       
    89 
       
    90         Log.log("StorageHandler committed");
       
    91 
       
    92         checkWaitAttribute(ball, "after storage commit");
       
    93 
       
    94         ball.iSifRegistrator.commitSession();
       
    95         Log.log("SifRegistrator committed");
       
    96 
       
    97         checkWaitAttribute(ball, "after sif commit");
       
    98 
       
    99         // ApplicationRegistrator session must be commited before
       
   100         // IntegrityService session so that temp icon files
       
   101         // can be removed.
       
   102         // Make synchronous commit so that the application
       
   103         // becomes visible to all parts of the system before
       
   104         // installer finishes.
       
   105         ball.iApplicationRegistrator.commitSession(true);
       
   106 
       
   107         Log.log("ApplicationRegistrator committed");
       
   108 
       
   109         checkWaitAttribute(ball, "after apparc commit");
       
   110 
       
   111         boolean result = ball.iIntegrityService.commit();
       
   112         if (!result)
       
   113         {
       
   114             InstallerException.internalError("IntegrityService commit failed");
       
   115         }
       
   116         Log.log("IntegrityService committed");
       
   117 
       
   118         checkWaitAttribute(ball, "after integrityservice commit");
       
   119 
       
   120         ball.iInstallationNotifier.finish(
       
   121             ball.iSuite.getUid(), ball.iInstallationNotifier.INSTALL_OK);
       
   122 
       
   123         // All sessions have been committed, do not throw
       
   124         // exceptions anymore after this point!
       
   125 
       
   126         Uid[] uids = ball.iSuite.getApplicationUids();
       
   127 
       
   128         try
       
   129         {
       
   130             // Notify platform that applications have been added or updated.
       
   131             ball.iSifRegistrator.notifyAppChange(
       
   132                 uids, (ball.iOldSuite != null?
       
   133                        ball.iSifRegistrator.APP_UPDATED:
       
   134                        ball.iSifRegistrator.APP_ADDED));
       
   135         }
       
   136         catch (Throwable t)
       
   137         {
       
   138             Log.logError("SifRegistrator.notifyAppChange failed", t);
       
   139         }
       
   140 
       
   141         if (ball.iCaptainMsgs)
       
   142         {
       
   143             // Notify JavaCaptain that application has been installed.
       
   144             Uid[] oldUids = null;
       
   145             if (ball.iOldSuite != null)
       
   146             {
       
   147                 oldUids = ball.iOldSuite.getApplicationUids();
       
   148             }
       
   149             ball.getCaptainService().appUpdated(oldUids, uids);
       
   150             Log.log("JavaCaptain notified");
       
   151         }
       
   152 
       
   153         String midletName = ball.getAttributeValue("MIDlet-Name");
       
   154         ball.log("Application " + midletName + " successfully installed.");
       
   155         ball.log(ball.iSuite.toShortString());
       
   156 
       
   157         // Store the uids to Installer static variable
       
   158         // in case CommsInstaller has to send them to
       
   159         // TCK Runner or preinstaller
       
   160         Installer.setInstalledUids(ball.iSuite.getUid(), uids);
       
   161 
       
   162         if (!ball.isSilent())
       
   163         {
       
   164             if (ball.getInstallerUi() != null && Platform.isS60())
       
   165             {
       
   166                 if (ball.LAUNCH_APP_QUERY)
       
   167                 {
       
   168                     // Set installation progress to 100% before
       
   169                     // displaying application launch query.
       
   170                     ball.iInstallationNotifier.set(
       
   171                         ball.iInstallationNotifier.getMax());
       
   172                     // Display launch application query to the user.
       
   173                     createLaunchAppQueryThread(ball);
       
   174                 }
       
   175             }
       
   176             if (Platform.isLinux() && ball.iCaptainMsgs)
       
   177             {
       
   178                 // Launch the installed application
       
   179                 try
       
   180                 {
       
   181                     // CaptainService.launchApp() uses RLC message.
       
   182                     //ball.getCaptainService().launchApp(uids[0]);
       
   183                     // CaptainService.startApp() uses installer specific
       
   184                     // message.
       
   185                     ball.getCaptainService().startApp(new Uid[] { uids[0] });
       
   186                 }
       
   187                 catch (InstallerException ie)
       
   188                 {
       
   189                     Log.log("Launching application failed: " + ie.toString());
       
   190                 }
       
   191             }
       
   192         }
       
   193     }
       
   194 
       
   195     public void cancel(ExeBall aBall)
       
   196     {
       
   197         // nop
       
   198     }
       
   199 
       
   200     /**
       
   201      * Constructs a new LaunchAppInfo object basing on given InstallBall.
       
   202      */
       
   203     private LaunchAppInfo createLaunchAppInfo(InstallBall aBall)
       
   204     {
       
   205         // Get suite icon InputStream.
       
   206         InputStream suiteIconInputStream = null;
       
   207         String suiteIconPath = aBall.iSuite.getAttributeValue("MIDlet-Icon");
       
   208         if (suiteIconPath != null)
       
   209         {
       
   210             try
       
   211             {
       
   212                 if (iJarFile == null)
       
   213                 {
       
   214                     // Temp files have already been deleted,
       
   215                     // get the icon from installed jar file.
       
   216                     iJarFile = new JarFile(aBall.iSuite.getJarPath());
       
   217                 }
       
   218                 suiteIconInputStream =
       
   219                     iJarFile.getInputStream
       
   220                     (new JarEntry(FileUtils.trimJarEntry(suiteIconPath)));
       
   221                 Log.log("LaunchAppInfo: suite icon " + suiteIconPath);
       
   222             }
       
   223             catch (IOException ioe)
       
   224             {
       
   225                 Log.logWarning("Getting InputStream for suite icon failed", ioe);
       
   226             }
       
   227         }
       
   228 
       
   229         // Get application icon InputStreams.
       
   230         InputStream[] appIconInputStreams = null;
       
   231         Vector appInfos = aBall.iSuite.getApplications();
       
   232         if (appInfos != null)
       
   233         {
       
   234             appIconInputStreams = new InputStream[appInfos.size()];
       
   235             try
       
   236             {
       
   237                 if (iJarFile == null)
       
   238                 {
       
   239                     // Temp files have already been deleted,
       
   240                     // get the icon from installed jar file.
       
   241                     iJarFile = new JarFile(aBall.iSuite.getJarPath());
       
   242                 }
       
   243                 for (int i = 0; i < appIconInputStreams.length; i++)
       
   244                 {
       
   245                     String iconPath =
       
   246                         ((com.nokia.mj.impl.installer.storagehandler.ApplicationInfo)
       
   247                          appInfos.elementAt(i)).getIconPath();
       
   248                     if (iconPath != null && iconPath.length() > 0)
       
   249                     {
       
   250                         appIconInputStreams[i] =
       
   251                             iJarFile.getInputStream
       
   252                             (new JarEntry(FileUtils.trimJarEntry(iconPath)));
       
   253                         Log.log("LaunchAppInfo: app icon " + i + ": " + iconPath);
       
   254                     }
       
   255                     else
       
   256                     {
       
   257                         appIconInputStreams[i] = null;
       
   258                         Log.log("LaunchAppInfo: app icon " + i + ": null");
       
   259                     }
       
   260                 }
       
   261             }
       
   262             catch (IOException ioe)
       
   263             {
       
   264                 Log.logWarning("Getting InputStream for application icon failed", ioe);
       
   265             }
       
   266         }
       
   267 
       
   268         return new LaunchAppInfo
       
   269                (ConfirmInstallation.getApplicationInfos(aBall),
       
   270                 appIconInputStreams, suiteIconInputStream, suiteIconPath);
       
   271     }
       
   272 
       
   273     /**
       
   274      * Creates and starts a new thread for asking launch
       
   275      * application query from the user.
       
   276      */
       
   277     private void createLaunchAppQueryThread(InstallBall aBall)
       
   278     {
       
   279         final InstallBall ball = aBall;
       
   280         ball.iDialogOpen = true;
       
   281         new Thread(new Runnable()
       
   282         {
       
   283             public void run()
       
   284             {
       
   285                 // Create and init LaunchAppinfo object.
       
   286                 LaunchAppInfo launchAppInfo = createLaunchAppInfo(ball);
       
   287                 // Display the query.
       
   288                 boolean launchApp =
       
   289                     ball.getInstallerUi().launchAppQuery(launchAppInfo);
       
   290 
       
   291                 // Close the jarFile and icon InputStreams.
       
   292                 if (iJarFile != null)
       
   293                 {
       
   294                     try
       
   295                     {
       
   296                         iJarFile.close(); // Closes also InputStreams
       
   297                         iJarFile = null;
       
   298                     }
       
   299                     catch (IOException ioe)
       
   300                     {
       
   301                         Log.logWarning("Closing icon InputStreams failed", ioe);
       
   302                     }
       
   303                 }
       
   304 
       
   305                 //if (ball.iSifRegistrator.getSifMode() > 0 && launchApp)
       
   306                 //{
       
   307                 //    ball.iSifRegistrator.launchAppView();
       
   308                 //}
       
   309                 //else
       
   310                 if (ball.iCaptainMsgs && launchApp &&
       
   311                         launchAppInfo.getApplications() != null &&
       
   312                         launchAppInfo.getApplications().length > 0)
       
   313                 {
       
   314                     int selection = launchAppInfo.getSelection();
       
   315                     Log.log("Launching application " + selection + ": " +
       
   316                             launchAppInfo.getApplications()[selection]
       
   317                             .getName());
       
   318                     ball.getCaptainService().startApp
       
   319                     (new Uid[] { launchAppInfo
       
   320                                  .getApplications()[selection]
       
   321                                  .getUid()
       
   322                                });
       
   323                 }
       
   324                 else
       
   325                 {
       
   326                     Log.log("No application launch");
       
   327                 }
       
   328 
       
   329                 synchronized (ball)
       
   330                 {
       
   331                     ball.iDialogOpen = false;
       
   332                     // Notify WaitForLaunchAppQuery step that
       
   333                     // we are finished with launch app query.
       
   334                     ball.notify();
       
   335                 }
       
   336             }
       
   337         }, "LaunchAppQueryThread").start();
       
   338     }
       
   339 
       
   340     /**
       
   341      * Wait a moment if Nokia-MIDlet-Install-Commit-Wait atribute has been set.
       
   342      */
       
   343     private static void checkWaitAttribute(InstallBall aBall, String aWaitMsg)
       
   344     {
       
   345         String commitWaitEnabled = System.getProperty(
       
   346                                        "com.nokia.mj.impl.installer.commitwaitenabled");
       
   347         if (commitWaitEnabled != null &&
       
   348                 commitWaitEnabled.equalsIgnoreCase("true"))
       
   349         {
       
   350             Log.log("commitWaitEnabled: " + commitWaitEnabled);
       
   351             String waitValue = aBall.getAttributeValue(
       
   352                                    "Nokia-MIDlet-Install-Commit-Wait");
       
   353             if (waitValue != null && waitValue.equalsIgnoreCase(aWaitMsg))
       
   354             {
       
   355                 try
       
   356                 {
       
   357                     int waitTime = 30; // secs
       
   358                     Log.log("Waiting " + waitTime + " secs " + aWaitMsg);
       
   359                     Thread.sleep(waitTime * 1000);
       
   360                 }
       
   361                 catch (InterruptedException ie)
       
   362                 {
       
   363                 }
       
   364             }
       
   365         }
       
   366     }
       
   367 }