widgettools/wrtwidgetpreinstaller/src/installwidgets.pl
branchRCL_3
changeset 32 fe49e33862e2
parent 31 b685c59de105
child 33 04b7640f6fb5
equal deleted inserted replaced
31:b685c59de105 32:fe49e33862e2
     1 #
       
     2 # Copyright (c) 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 use strict;
       
    18 use warnings;
       
    19 use File::Spec::Functions;
       
    20 use Getopt::Long;
       
    21 use Pod::Usage;
       
    22 
       
    23 # Version of the script - just use the date
       
    24 $main::VERSION = '12-July-2010';
       
    25 
       
    26 # New getopt::long provides this - but old version doesn't?
       
    27 sub version
       
    28   {
       
    29   print sprintf("$0: $main::VERSION\n$^X: %vd\nos: $^O", $^V);
       
    30   exit;
       
    31   }
       
    32 
       
    33 # Get arguments
       
    34 my ( $help, $version, $verbose, $debug, $epocroot, $l10n );
       
    35 GetOptions( "help" => \$help, "version|ver" => \$version,
       
    36       "verbose|v" => \$verbose,  "debug" => \$debug,
       
    37       "epocroot|e=s" => \$epocroot, "localization|l=s" => \$l10n )
       
    38   or pod2usage('Invalid parameters');
       
    39 
       
    40 # Handle help and version
       
    41 pod2usage({ verbose => 1, exitval => 0}) if $help;
       
    42 version() if $version;
       
    43 
       
    44 # Interpret arguments
       
    45 $verbose = 1 if $debug;
       
    46 $verbose = $verbose ? '-v' : '';
       
    47 $epocroot = $ENV{EPOCROOT} if !$epocroot;
       
    48 
       
    49 # Interpret localization l10n argument
       
    50 
       
    51 # There are two modes.  In one mode you specify the location of a
       
    52 # lproj.xml file and the code computes l10n files for all languages so
       
    53 # that runtime locale selection should work.  In the other mode you
       
    54 # specify a language code (example, fr for French) and the code
       
    55 # computes l10n just for that language.
       
    56 $l10n = '' if !$l10n;
       
    57 my $lproj = '';
       
    58 if ($l10n =~ /lproj\.xml$/i)
       
    59   {
       
    60   $lproj = $l10n;
       
    61   $l10n = '';
       
    62   }
       
    63 
       
    64 my ($configini, @unnecessary) = @ARGV;
       
    65 
       
    66 if ($configini)
       
    67   {
       
    68   # There shouldn't be any need for any other arguments
       
    69   pod2usage('Unnecessary arguments supplied.') if @unnecessary;
       
    70 
       
    71   # Now do the installation
       
    72   my $installer = WidgetInstaller->new('verbose' => $verbose, 'debug' => $debug, 'epocroot' => $epocroot, 'lproj' => $lproj, 'l10n' => $l10n);
       
    73   $installer->installConfig($configini);
       
    74   }
       
    75 else
       
    76   {
       
    77   pod2usage('Missing config.ini argument.');
       
    78   }
       
    79 
       
    80 # ***
       
    81 # Package for installing Widgets
       
    82 #
       
    83 
       
    84 package WidgetInstaller;
       
    85 
       
    86 use File::Spec::Functions;
       
    87 use File::Path;
       
    88 use File::Basename;
       
    89 use Unicode::String qw(utf8 utf16);
       
    90 use File::Temp qw/tempdir/;
       
    91 use File::Copy;
       
    92 use XML::Parser;
       
    93 use Data::Dumper;
       
    94 use XML::Simple;
       
    95 
       
    96 # CONSTANTS
       
    97 use constant ICON_SIZES => "88,32,24";      # Size of icons to generate in the MBM file
       
    98 #use constant INTERNAL_UID_LOWER => 0x2000DAD2; # Lower UID bound for midlets installed to internal drives and rom
       
    99 #use constant EXTERNAL_UID_LOWER => 0x2000DCC6; # Lower UID bound for midlets installed to removable cards
       
   100 use constant INTERNAL_UID_LOWER_WRT => 0x2000DAD2;  # Lower UID bound for WRT widgets installed to internal drives and rom
       
   101 use constant INTERNAL_UID_LOWER_CWRT => 0x2000DBCC; # Lower UID bound for CWRT widgets installed to internal drives and rom
       
   102 use constant EXTERNAL_UID_LOWER_WRT => 0x2000DCC6;  # Lower UID bound for WRT widgets installed to removable cards
       
   103 use constant EXTERNAL_UID_LOWER_CWRT => 0x2000DDC0; # Lower UID bound for CWRT widgets installed to removable cards
       
   104 use constant WIDGET_UI_UID => 0x10282822;   # UID of the widget app
       
   105 use constant CWRT_WIDGET_UI_UID => 0x200267C0;    # UID of the cwrt widget app
       
   106 use constant SWIDGET_UI_UID => 0x102829A0;	# UID of the securewidget app
       
   107 use constant CWRT_WIDGET_UI_NON_NOKIA_UID => 0x200267D6;    # UID of the cwrt widget app
       
   108 
       
   109 # Folder paths
       
   110 use constant DESTINATION => 'private/10003a3f/import/apps/NonNative/Resource';
       
   111 use constant ROM_DEST => 'epoc32/release/winscw/udeb/Z/';
       
   112 use constant DRIVE_DEST => 'epoc32/winscw/%s';
       
   113 use constant WIDGET_REGISTRY => 'private/10282f06/WidgetEntryStore.xml';
       
   114 use constant CWRT_WIDGET_REGISTRY => 'private/10282f06/CWRTWidgetEntryStore.xml';
       
   115 use constant CWRT_WEBAPP_REGISTRY => 'private/200267D9/webapp_registry.db';
       
   116 use constant CWRT_ACCESS_POLICY_PATH => 'browser_access_policy.xml';
       
   117 use constant WIDGET_NAME => 'en-gb/widget/name';
       
   118 use constant WIDGET_PROCESSUID => 'processUid';
       
   119 use constant WIDGET_ID => 'widget/id';
       
   120 use constant WIDGET_VERSION => 'widget/version';
       
   121 use constant WIDGET_CONTENT => 'widget/content';
       
   122 use constant WIDGET_FEATURE => 'widget/feature/';
       
   123 use constant WIDGET_FEATURE_PARAM => '/param/';
       
   124 use constant WIDGET_ACCESS => 'widget/access/';
       
   125 use constant WIDGET_HEIGHT => 'widget/height';
       
   126 use constant WIDGET_WIDTH => 'widget/width';
       
   127 use constant WIDGET_NOKIA_SHAREDLIB => 'widget/NOKIA:sharedlibrary';
       
   128 use constant WIDGET_NOKIA_SHAREDLIB_FOLDER => 'widget/NOKIA:sharedlibrary/NOKIA:folder';
       
   129 use constant WIDGET_NOKIA_SHAREDLIB_WIDGET => 'widget/NOKIA:sharedlibrary/NOKIA:widget';
       
   130 use constant WIDGET_NOKIA_SHAREDLIB_ICON => 'widget/NOKIA:sharedlibrary/NOKIA:icon';
       
   131 use constant KEY_VALUE_SEPERATOR => ',';
       
   132 use constant KEY_VALUE_PAIR_SEPERATOR => ';';
       
   133 use constant KEY_ATTR_SEPERATOR => ':';
       
   134 
       
   135 our $w3c_widget = 0 ;
       
   136 our $hashval;
       
   137 our $non_nokia_widget = 0;
       
   138 our ($isSharedLibrary, $sharedFolderName ,$isSharedWidget, $isSharedIcon)= (0,'',0,0);
       
   139 our (@staticUidWrtIntList,@staticUidCwrtIntList,@staticUidWrtExtList,@staticUidCwrtExtList) = ({},{},{},{});
       
   140 our $isSecureWidget = 0;
       
   141 
       
   142 # Create a new object
       
   143 sub new
       
   144   {
       
   145   my $invocant = shift;
       
   146   my $self = bless({}, ref $invocant || $invocant);
       
   147 
       
   148   my %args = @_;
       
   149   $self->{'args'} = \%args;
       
   150   $self->{'args'}->{'verbose'} = $self->{'args'}->{'verbose'} ? '-v' : '';
       
   151 
       
   152   $self->{'installedFiles'} = ();
       
   153   $self->{'freeuidwrtint'} = INTERNAL_UID_LOWER_WRT;
       
   154   $self->{'freeuidwrtext'} = EXTERNAL_UID_LOWER_WRT;
       
   155   $self->{'freeuidcwrtint'} = INTERNAL_UID_LOWER_CWRT;
       
   156   $self->{'freeuidcwrtext'} = EXTERNAL_UID_LOWER_CWRT;
       
   157   $self->{'langmapping'} = $self->getLangMapping($self->{'args'}->{'lproj'}) unless $self->{'args'}->{'l10n'};
       
   158   
       
   159   #Check if localisation argument is land number ID; If true, get the lang Name using langmapping file - Widget_lproj.xml 
       
   160   if ($l10n =~ /\d+$/)
       
   161   {
       
   162     print "\nLANG ID given as localisation argument :: $l10n \n";
       
   163     $self->{'langmapping'} = $self->getLangMapping();
       
   164     
       
   165     if($self->{'langmapping'})
       
   166     {
       
   167       # Iterate through all the languages we know about
       
   168       for(my $i = 0; $i < scalar(@{ $self->{'langmapping'}->{LangID} }); $i++)
       
   169       {
       
   170         my ( $langid, $langname ) = ( $self->{'langmapping'}->{LangID}->[$i], $self->{'langmapping'}->{LangDir}->[$i] );
       
   171         if($l10n == $langid)
       
   172         {
       
   173           print "Setting argument to LangName - $langname \n";
       
   174           $self->{'args'}->{'l10n'} = lc($langname);
       
   175           last;
       
   176         }
       
   177       }
       
   178     }
       
   179   }
       
   180 
       
   181   return $self;
       
   182   }
       
   183   
       
   184 # Gets the language mapping from the Widget_lproj.xml file
       
   185 sub getLangMapping
       
   186   {
       
   187   my ( $self, $lproj ) = @_;
       
   188 
       
   189   # Get the LPROJ file which specifies lang id mappings
       
   190   if (!$lproj)
       
   191     {
       
   192     (my $EPOCROOT = $ENV{EPOCROOT}) =~ s/[\/\\]+$//;
       
   193     $lproj = WidgetInstaller::fixFilename("${epocroot}epoc32/winscw/c/private/10282f06/Widget_lproj.xml");
       
   194     $lproj = WidgetInstaller::fixFilename("$EPOCROOT/epoc32/winscw/c/private/10282f06/Widget_lproj.xml") if !-e $lproj;
       
   195     $lproj = WidgetInstaller::fixFilename("${epocroot}epoc32/data/Z/private/10282f06/Widget_lproj.xml") if !-e $lproj;
       
   196     $lproj = WidgetInstaller::fixFilename("$EPOCROOT/epoc32/data/Z/private/10282f06/Widget_lproj.xml") if !-e $lproj;
       
   197     $lproj = WidgetInstaller::fixFilename("${epocroot}S60/mw/web/WebEngine/WidgetRegistry/Data/Widget_lproj.xml") if !-e $lproj;
       
   198     $lproj = WidgetInstaller::fixFilename("$EPOCROOT/S60/mw/web/WebEngine/WidgetRegistry/Data/Widget_lproj.xml") if !-e $lproj;
       
   199     $lproj = WidgetInstaller::findCmd('Widget_lproj.xml') if !-e $lproj;
       
   200     $lproj = WidgetInstaller::findCmd('internal/Widget_lproj.xml') if !-e $lproj;
       
   201     undef $lproj if !-e $lproj;
       
   202 
       
   203     # Display a warning if localisation can't be performed
       
   204     warn "WARNING: Can't find Widget_lproj.xml - localisation is disabled.\n" if !$lproj;
       
   205     }
       
   206 
       
   207   # Load the mapping file
       
   208   if ($lproj)
       
   209     {
       
   210     die "Can't find $lproj file." if !-e $lproj;
       
   211     print "Localisation support enabled using config: $lproj\n" if $verbose;
       
   212     my $mapping = XMLin($lproj);
       
   213     print "Found ", scalar(@{ $mapping->{'LangID'} }), " language mappings.\n" if $verbose;
       
   214     return $mapping;
       
   215     }
       
   216   }
       
   217 
       
   218 # Install Widgets listed in config file
       
   219 # Format is as follows where "drive-z" specifies widgets for drive z: etc...
       
   220 # Comments are okay - they start with a # character
       
   221 # If the file doesn't exist as given then EPOCROOT is prepended to the filename to try and find it
       
   222 #
       
   223 # You can specify whether a widget is intended for the homescreen by adding the text [HomeScreen] after the filename
       
   224 # This will set the BlanketPermissionGranted attribute in the registry.
       
   225 # Widgets intended for the homescreen must have the MiniViewEnabled attribute set in its PLIST file otherwise an error is generated.
       
   226 #
       
   227 # You can specify commands to run before exit after a [run-commands] or [homescreen-processor] 
       
   228 #
       
   229 # [drive-z]
       
   230 # \path\widget1.wgz
       
   231 # widget2.wdgt.zip [HomeScreen]
       
   232 #
       
   233 # [drive-e]
       
   234 # widget3.wgz
       
   235 #
       
   236 # [run-commands]
       
   237 # dostuff.pl
       
   238 #
       
   239 
       
   240 sub installConfig
       
   241   {
       
   242   my ( $self, $file ) = @_;
       
   243   $self->{'installedFiles'} = ();
       
   244 
       
   245   my ( %installData, $sectionName );
       
   246   open CONFIG, $file or die "Failed to open config file $file: $!";
       
   247   
       
   248   # Loop for gathering STATIC UIDs allocated for widgets in config INI file
       
   249   while(my $line = <CONFIG>)
       
   250   {
       
   251     # Ignore comments
       
   252     $line =~ s/\#.*$//;
       
   253     
       
   254     if ($line =~ /^\[([^\]]+)\]/)
       
   255       {
       
   256       $sectionName = lc $1;
       
   257       next;
       
   258       }
       
   259 
       
   260     # Process sections after this point
       
   261     next if !$sectionName;
       
   262     chomp $line;
       
   263 
       
   264     # Have we found a list of widgets?
       
   265     if ($sectionName =~ /^drive-([a-z])/)
       
   266     {
       
   267       my $drive = uc($1);
       
   268       #Assuming Static UID given in ini are within int/ext/wgt/wgz specified ranges
       
   269       # Add Static UID to the respective list
       
   270       if ($line =~ /^(.+?\.(?:wdgt\.zip|wgz|wgt))\s*(\[HomeScreen\])?\s*(0x[a-fA-F0-9]{8})?\s*(\[Operator\])?\s*$/i)
       
   271       {
       
   272         if ($3)
       
   273         {
       
   274           my $uid = hex($3);
       
   275           
       
   276           if ($drive =~ /^[zcZC]/)
       
   277           {
       
   278             if(($uid >= INTERNAL_UID_LOWER_WRT) && ($uid < INTERNAL_UID_LOWER_CWRT))
       
   279             {
       
   280               push(@staticUidWrtIntList,$uid) ;
       
   281             }
       
   282             else
       
   283             {
       
   284               push(@staticUidCwrtIntList,$uid);
       
   285             }
       
   286           }
       
   287           else
       
   288           {
       
   289             if(($uid >= EXTERNAL_UID_LOWER_WRT) && ($uid < EXTERNAL_UID_LOWER_CWRT))
       
   290             {
       
   291               push(@staticUidWrtExtList,$uid) ;
       
   292             }
       
   293             else
       
   294             {
       
   295               push(@staticUidCwrtExtList,$uid) ;
       
   296             }
       
   297           }
       
   298         }
       
   299       }
       
   300     }
       
   301   }
       
   302   close CONFIG;
       
   303   @staticUidWrtIntList = sort(@staticUidWrtIntList);
       
   304   print "SORTED WRT INTERNAL STATIC UID  @staticUidWrtIntList \n";
       
   305   @staticUidCwrtIntList = sort(@staticUidCwrtIntList);
       
   306   print "SORTED CWRT INTERNAL STATIC UID  @staticUidCwrtIntList \n";
       
   307   @staticUidWrtExtList = sort(@staticUidWrtExtList);
       
   308   print "SORTED WRT EXTERNAL STATIC UID @staticUidWrtExtList \n";
       
   309   @staticUidCwrtExtList = sort(@staticUidCwrtExtList);
       
   310   print "SORTED CWRT EXTERNAL STATIC UID @staticUidCwrtExtList \n";
       
   311   
       
   312   open CONFIG, $file or die "Failed to open config file $file: $!";
       
   313   # Main loop which reads the config INI line by line and installs widgets[wgz/wgt] in respective drives
       
   314   while(my $line = <CONFIG>)
       
   315     {
       
   316     # Ignore comments
       
   317     $line =~ s/\#.*$//;
       
   318 
       
   319     if ($line =~ /^\[([^\]]+)\]/)
       
   320       {
       
   321       $sectionName = lc $1;
       
   322       
       
   323       # Remember destination if any specified
       
   324       if ($sectionName =~ /^drive-([a-z])=(.+)$/)
       
   325         {
       
   326         $self->{'destination'}->{uc($1)} = $2;
       
   327         }
       
   328       next;
       
   329       }
       
   330 
       
   331     # Process sections after this point
       
   332     next if !$sectionName;
       
   333     chomp $line;
       
   334 
       
   335     # Have we found a list of widgets?
       
   336     if ($sectionName =~ /^drive-([a-z])/)
       
   337       {
       
   338       my $drive = uc($1);
       
   339       
       
   340       # Add to the list of Widget files
       
   341       if ($line =~ /^(.+?\.(?:wdgt\.zip|wgz|wgt))\s*(\[HomeScreen\])?\s*(0x[a-fA-F0-9]{8})?\s*(\[Operator\])?\s*$/i)
       
   342         {
       
   343         my $widget = $1;
       
   344         $widget = fixFilename(catfile($self->{'args'}->{'epocroot'}, $1)) if !-e $widget;
       
   345         die "Can't find widget $widget" if !-e $widget;
       
   346         $self->{'homescreen'}{lc $widget} = 1 if $2; # Intended for the homescreen?
       
   347         $self->{'staticUID'}{lc $widget} = hex($3) if $3;
       
   348         $self->{'secure'}{lc $widget} = 0;
       
   349         $self->{'operator'}{lc $widget} = 1 if $4;
       
   350         print "Widget for drive $drive: $widget\n" if $self->{'args'}->{'verbose'};
       
   351         push @{ $installData{"$drive:"} }, $widget;
       
   352         }
       
   353       elsif ($line =~ /^(.+?\.(?:wdgt\.zip|wgz))\s*(\[Secure\])?\s*(0x[a-fA-F0-9]{8})?\s*$/i)
       
   354         {
       
   355           my $widget = $1;
       
   356           $widget = fixFilename(catfile($self->{'args'}->{'epocroot'}, $1)) if !-e $widget;
       
   357           die "Can't find widget $widget" if !-e $widget;
       
   358           $self->{'secure'}{lc $widget} = 1 if $2; # Intended for a secure widget handling?
       
   359           $self->{'staticUID'}{lc $widget} = hex($3) if $3;
       
   360           print "Widget for drive $drive: $widget\n" if $self->{'args'}->{'verbose'};
       
   361           push @{ $installData{"$drive:"} }, $widget;
       
   362         }
       
   363       else
       
   364       	{
       
   365       		my $widget = $1;
       
   366       		$self->{'secure'}{lc $widget} = 0;
       
   367         }	
       
   368       }
       
   369     # Retrieve the command to execute before exit
       
   370     elsif ($sectionName =~ /^(run-commands|homescreen-processor)$/i && $line)
       
   371       {
       
   372       push @{ $self->{'exitcmds'} }, $line;
       
   373       }
       
   374     }
       
   375   close CONFIG;
       
   376 
       
   377   # Now intall the widgets for each drive specified in the config file
       
   378   foreach my $drive ( keys %installData )
       
   379     {
       
   380     $self->installFiles($drive, $installData{$drive} );
       
   381     $self->makeIBY($drive);
       
   382     $self->makeIBY($drive, 'localised') unless $self->{'args'}->{'l10n'};
       
   383     }
       
   384   
       
   385   # Exit commands at the end of the process
       
   386   if ($self->{'exitcmds'})
       
   387     {
       
   388     foreach my $cmd ( @{ $self->{'exitcmds'} } )
       
   389       {
       
   390       print "Executing: $cmd\n" if $self->{'args'}->{'verbose'};
       
   391       warn "WARNING: error running $cmd" if system($cmd) != 0;
       
   392       }
       
   393     }
       
   394   }
       
   395 
       
   396 # ***
       
   397 # Installs files to a drive
       
   398 #
       
   399 sub installFiles
       
   400   {
       
   401   my ( $self, $drive, $fileList ) = @_;
       
   402   my $startsrc ;
       
   403     my $iconsrc ;
       
   404   
       
   405    $isSharedLibrary = 0;
       
   406    $isSharedWidget = 0;
       
   407    $isSharedIcon = 0;
       
   408    $sharedFolderName ='';
       
   409    $isSecureWidget = 0;
       
   410     
       
   411   print "Installing files for drive $drive\n" if $self->{'args'}->{'verbose'};
       
   412 
       
   413   # Unregister any existing widgets as otherwise when the registry is rewritten their icons will appear in the emulator but they won't work
       
   414   $self->unregisterWidgets($drive);
       
   415 
       
   416   print "\n			INSTALLING FILES FOR DRIVE $drive				\n"; 
       
   417   # Process each widget in turn
       
   418   my ( @installedProps );
       
   419   my ( @installedCWRTProps );
       
   420   foreach my $filename ( @$fileList )
       
   421     {
       
   422     # Check the file exists
       
   423     die "Can't find $filename" if !-e $filename;
       
   424 
       
   425     # Create a temporary folder
       
   426     print "\nInstalling $filename\n";
       
   427     my $tempdir = tempdir ( DIR => '.', CLEANUP => !$self->{args}->{'debug'});
       
   428 
       
   429     # Prefer to use 7zip rather than unzip because it's better behaved wrt Unicode
       
   430     if (findCmd('7z.exe'))
       
   431       {
       
   432       $self->un7zipWidget($filename, $tempdir);
       
   433       }
       
   434     else
       
   435       {
       
   436       $self->unzipWidget($filename, $tempdir);
       
   437       }
       
   438         my $widgetdata ;
       
   439         
       
   440         $isSharedLibrary = 0;
       
   441         $isSharedWidget = 0;
       
   442         $isSharedIcon = 0;
       
   443         $sharedFolderName ='';
       
   444     
       
   445     my ( $root, $extracted, $size ) = $self->getFiles($tempdir);
       
   446     die "No files extracted from $filename" if !@$extracted;
       
   447     
       
   448     if ($self->{'operator'}{lc $filename})
       
   449 		{
       
   450     	print "\n NON NOKIA WGT \n";
       
   451     	$non_nokia_widget = 1;
       
   452     }
       
   453     else
       
   454     {
       
   455     	print "\n NOKIA WGT \n";
       
   456     	$non_nokia_widget = 0;
       
   457     }
       
   458     
       
   459     
       
   460     if (($filename =~ /.wgz/ )&& (my $plist = catfile($tempdir, $root, 'Info.plist')))
       
   461       {
       
   462           print ("S60 widget \n");
       
   463           
       
   464           $w3c_widget = 0;
       
   465           # Parse the XML file into a hash
       
   466               $widgetdata = parsePList($plist);
       
   467       }
       
   468     elsif (($filename =~ /.wgt/ ) && ( my $confxml = catfile($tempdir, $root, 'config.xml')))
       
   469       {
       
   470         print (" W3C widget \n"); 
       
   471       
       
   472           # Parse the XML file into a hash
       
   473             $widgetdata = parseConfXml($confxml,$self->{'args'}->{'l10n'});
       
   474             $w3c_widget = 1;
       
   475       }
       
   476     else
       
   477       {
       
   478       die "Can't find $root/Info.plist , $root/config.xml file";
       
   479       }       
       
   480 		
       
   481 	  if ($self->{'secure'}{lc $filename}){
       
   482 		$isSecureWidget = 1;
       
   483 	  } else {
       
   484 	  	$isSecureWidget = 0;
       
   485 	  }
       
   486 
       
   487     if( $w3c_widget )
       
   488     { 
       
   489       if( $widgetdata->{'MainHTML'} )
       
   490         {
       
   491         $startsrc = $widgetdata->{'MainHTML'};
       
   492         }
       
   493       else
       
   494         {
       
   495         $startsrc = 'index.html';
       
   496         }
       
   497       if( $widgetdata->{'IconPath'} )
       
   498         {
       
   499         $iconsrc = $widgetdata->{'IconPath'};
       
   500         }
       
   501       else
       
   502         {
       
   503         $iconsrc = 'icon.png';   
       
   504         }
       
   505         
       
   506   		if($non_nokia_widget)
       
   507   		{
       
   508   			$widgetdata->{'ProcessUid'} = CWRT_WIDGET_UI_NON_NOKIA_UID;
       
   509   		}
       
   510   		else
       
   511   		{
       
   512       		$widgetdata->{'ProcessUid'} = CWRT_WIDGET_UI_UID;
       
   513       	}
       
   514       
       
   515       $widgetdata->{'MimeType'} = "application/widget";
       
   516     }         
       
   517 
       
   518     print "Identifier: $widgetdata->{'BundleIdentifier'}\n" if $self->{args}->{'verbose'};
       
   519     
       
   520     # Set widget package properties
       
   521     $widgetdata->{'FileName'} = $filename;
       
   522     $widgetdata->{'FileSize'} = $size;
       
   523 
       
   524     # Load the language translations for BundleDisplayName
       
   525     if ($self->{'args'}->{'l10n'})
       
   526       {
       
   527       my $localised = $self->getLocalisedStringByLangCode(catfile($tempdir, $root), 'DisplayName', $self->{'args'}->{'l10n'});
       
   528       $widgetdata->{'BundleDisplayName'} = $localised if $localised;
       
   529       }
       
   530     else
       
   531       {
       
   532       $widgetdata->{'LocBundleDisplayName'} = $self->getLocalisedStrings(catfile($tempdir, $root), 'DisplayName');
       
   533       }
       
   534 
       
   535     # Fix up some of the fields
       
   536     $widgetdata->{'BundleName'} = $widgetdata->{'BundleDisplayName'} if !$widgetdata->{'BundleName'};
       
   537     $widgetdata->{'AllowNetworkAccess'} = $widgetdata->{'AllowFullAccess'} if !$widgetdata->{'AllowNetworkAccess'};
       
   538     $widgetdata->{'DriveName'} = $drive;
       
   539     
       
   540     if( $w3c_widget )
       
   541       {
       
   542       $widgetdata->{'PropertyListVersion'} = 4;
       
   543       my $widget_uid;
       
   544       
       
   545       if($non_nokia_widget)
       
   546   		{
       
   547   			$widget_uid = CWRT_WIDGET_UI_NON_NOKIA_UID;
       
   548   		}
       
   549   		else
       
   550   		{
       
   551       	$widget_uid = CWRT_WIDGET_UI_UID;
       
   552       }
       
   553       
       
   554       if($isSharedLibrary)
       
   555       {
       
   556         #In case of NOKIA:sharedlibrary, the extracted widget contents and data source are stored under private\<uid>\..\lib\<sharedfoldername>\
       
   557         $widgetdata->{'BasePath'} = sprintf('%s\\private\\%08X\\%s\\%s\\%s\\', $widgetdata->{'DriveName'}, $widget_uid, "widgets_21D_4C7","lib",$sharedFolderName);
       
   558         $widgetdata->{'IconPath'} = sprintf('%s\\private\\%08X\\%s\\%s\\%s\\',$widgetdata->{'DriveName'}, $widget_uid, "data" ,"lib" ,$sharedFolderName);
       
   559       }
       
   560       else
       
   561       {
       
   562         $widgetdata->{'BasePath'} = sprintf('%s\\private\\%08X\\%s\\%s\\', $widgetdata->{'DriveName'}, $widget_uid, "widgets_21D_4C7", hashpjw($widgetdata->{'BundleIdentifier'}));
       
   563         $widgetdata->{'IconPath'} = sprintf('%s\\private\\%08X\\%s\\%s\\',$widgetdata->{'DriveName'}, $widget_uid, "data" , hashpjw($widgetdata->{'BundleIdentifier'}));
       
   564       }
       
   565       $widgetdata->{'MainHTML'} = "$widgetdata->{'BasePath'}$startsrc";
       
   566       $widgetdata->{'AllowNetworkAccess'} = 1;
       
   567       
       
   568       }
       
   569     else
       
   570       {
       
   571       $widgetdata->{'PropertyListVersion'} = 1;
       
   572       $widgetdata->{'BasePath'} = sprintf('%s\\private\\%08x\\%s\\', $widgetdata->{'DriveName'}, WIDGET_UI_UID, $widgetdata->{'BundleIdentifier'});
       
   573       $widgetdata->{'MainHTML'} = "$widgetdata->{'BasePath'}$root\\$widgetdata->{'MainHTML'}";
       
   574       $widgetdata->{'IconPath'} = "$widgetdata->{'BasePath'}$root\\";
       
   575       }
       
   576       
       
   577     $widgetdata->{'BlanketPermissionGranted'} = 0 if( ! $widgetdata->{'BlanketPermissionGranted'} );
       
   578     $widgetdata->{'MiniViewEnabled'} = 0  if( ! $widgetdata->{'MiniViewEnabled'} );
       
   579     
       
   580     # Indicate that the widget was pre-installed
       
   581     $widgetdata->{'PreInstalled'} = 1;
       
   582     
       
   583     # Set BlanketPermissionGranted flag if Widget is listed as a homescreen widget in the INI file
       
   584     # Error if MiniViewEnabled isn't set
       
   585     if ($self->{'homescreen'}{lc $filename})
       
   586       {
       
   587       $widgetdata->{'BlanketPermissionGranted'} = 1;
       
   588       die "ERROR: $filename - MiniViewEnabled not set for homescreen widget" if !$widgetdata->{'MiniViewEnabled'};
       
   589       }
       
   590 
       
   591     # Defining UID  
       
   592     if($self->{'staticUID'}{lc $filename})
       
   593       {
       
   594       print "Using Static UID from INI file\n";
       
   595       $widgetdata->{'Uid'} = $self->{'staticUID'}{lc $filename};
       
   596       }
       
   597     else
       
   598       {
       
   599       # Find the next free UID to use
       
   600       $widgetdata->{'Uid'} = $self->findfreeUid($widgetdata);
       
   601       }
       
   602     print sprintf("Using UID for midlet: 0x%08X\n", $widgetdata->{'Uid'}) if $self->{args}->{'verbose'};
       
   603 
       
   604     # Make sure the destination exists
       
   605     my $dest = $self->regFileName($drive);
       
   606     mkpath $dest;
       
   607 
       
   608     my $icon;
       
   609     if($w3c_widget)
       
   610     {
       
   611       my $locate = $self->{'args'}->{'l10n'};
       
   612       my $seperator ='-';
       
   613       my $position = -1;
       
   614       my $found = 0 ;
       
   615       if ($self->{'args'}->{'l10n'})
       
   616           {
       
   617             do
       
   618                {
       
   619                 my $searchdir = '.\\'.$tempdir.'\\locales\\'.$locate;
       
   620                 if( opendir(DIR, $searchdir))
       
   621                     {
       
   622                     my @files = grep(/$iconsrc$/,readdir(DIR));
       
   623                     closedir(DIR);
       
   624                     if(@files)
       
   625                        {
       
   626                         $iconsrc = 'locales\\'.$locate.'\\'.$iconsrc ;
       
   627                         $found = 1;
       
   628                        }
       
   629                     }  
       
   630                 if(($position = rindex($locate,$seperator)) > 0 )
       
   631                     {
       
   632                     $locate = substr($locate,0,$position);
       
   633                     }
       
   634                } while (!$found && $position > 0);
       
   635           }
       
   636           if ($iconsrc)
       
   637           {
       
   638             $icon = catfile($tempdir, $root, $iconsrc);    
       
   639           }
       
   640             
       
   641           if(-e $icon)
       
   642           {
       
   643              $widgetdata->{'DBIconPath'}= "$widgetdata->{'BasePath'}$iconsrc";
       
   644              print "Icon found -- $widgetdata->{'DBIconPath'} \n";
       
   645           }
       
   646           else
       
   647           {
       
   648               $icon = findCmd('default_widget_icon.png');
       
   649               print "default_widget_icon.png used \n";    
       
   650               $widgetdata->{'DBIconPath'}= ":/resource/default_widget_icon.png";
       
   651           }
       
   652       }
       
   653     else
       
   654     {
       
   655       $icon = catfile($tempdir, $root, 'Icon.png');
       
   656             die "ERROR: Widget bundle must include an Icon.png file in $root directory.\n" unless -e $icon;
       
   657     }
       
   658     
       
   659     # Create the MBM file icon - in case of sharedlibrary, create only if NOKIA:widget is true
       
   660     my $mbm;
       
   661     
       
   662     print("\nIs shared library - $isSharedLibrary \nIs sharedlib widget - $isSharedWidget \nIs Secure WGZ - $self->{'secure'}{lc $filename}\n");
       
   663     
       
   664 		if( ((!$isSharedLibrary) || ($isSharedLibrary && $isSharedWidget)) && (!$self->{'secure'}{lc $filename}))
       
   665     {
       
   666     	  print "Creating mbm !!!\n";
       
   667         die "ERROR: Can't find PNG2MBM command in PATH." if !(my $cmd = findCmd('png2mbm.exe'));
       
   668         $mbm = $self->regFileName($drive, sprintf("[%08x].mbm", $widgetdata->{'Uid'}));
       
   669         print "Generating: $mbm\n";
       
   670                     die "Failed to create MBM $mbm " if system("$cmd $self->{args}->{'verbose'} -in \"$icon\" -out $mbm -sizes ".ICON_SIZES) != 0;
       
   671     
       
   672         # Add the mbm to the list of files
       
   673         $self->addToRomList($drive, $mbm);
       
   674     
       
   675         # Create the INI file which defines the registry info
       
   676         my $ini = catfile($tempdir, 'reg.ini');
       
   677         $self->makeIni($widgetdata, $ini);
       
   678         unlink 'debug.ini'; copy($ini, 'debug.ini') if $debug;
       
   679         print "Generated INI file: $ini\n" if $self->{args}->{'verbose'};
       
   680     
       
   681         # Generate the registry files
       
   682         die "ERROR: Can't find WidgetRegFiles.exe command in PATH." if !($cmd = findCmd('WidgetRegFiles.exe'));
       
   683         die "Failed to generate registry files" if system("$cmd $ini") != 0;
       
   684         my ( $reg, $loc ) = ( catfile($dest, sprintf("%08x_reg.rsc", $widgetdata->{'Uid'})), catfile($dest, sprintf("%08x_loc.rsc", $widgetdata->{'Uid'})) );
       
   685         die "Failed to generate REG file: $!" if !-e $reg;
       
   686         $self->addToRomList($drive, $reg);
       
   687         die "Failed to generate LOC file: $!" if !-e $loc;
       
   688         if ($self->{'args'}->{'l10n'})
       
   689           {
       
   690               $self->addToRomList($drive, $loc);
       
   691           }
       
   692         else
       
   693           {
       
   694               $self->addToRomList($drive, $loc, 'localised');
       
   695           }
       
   696         }
       
   697         
       
   698     # Create install folder
       
   699     my $dir = $self->installDir($drive, $widgetdata->{'BundleIdentifier'});
       
   700     mkpath $dir;
       
   701 
       
   702     # Now copy the widget files to the right place
       
   703     print "Install Directory: $dir\n";
       
   704     foreach my $widgetfile ( @$extracted )
       
   705     {
       
   706       my ( $sourceFile, $destFile ) = ( catfile($tempdir, $widgetfile), catfile($dir, $widgetfile) );
       
   707       print "Copying $sourceFile to $destFile\n" if $self->{args}->{'debug'};
       
   708 
       
   709       # Create the directory if it doesn't exist already
       
   710       my $dir = dirname($destFile);
       
   711       if (!-d $dir)
       
   712         {
       
   713         mkpath ($dir) or die "Failed to create $dir $!";
       
   714         }
       
   715       unlink $destFile;
       
   716       if (!copy($sourceFile, $destFile))
       
   717         {
       
   718         warn "WARNING: Failed to copy $sourceFile to $destFile: $!";
       
   719         }
       
   720       #else
       
   721         {
       
   722         $self->addToRomList($drive, $destFile);
       
   723         }
       
   724     }
       
   725 
       
   726     # Copy the MBM file into the widget install directory
       
   727     # because native installation does and uses it after
       
   728     # installation to manage UID consistency.
       
   729     if( (!$isSharedLibrary) || ($isSharedLibrary && $isSharedWidget))
       
   730     {
       
   731         my $mbmName = sprintf("[%08x].mbm", $widgetdata->{'Uid'});
       
   732         my $destFile;
       
   733         if($w3c_widget)
       
   734         {
       
   735             my $dataDir;
       
   736             
       
   737             my $widget_uid;
       
   738       
       
   739 			      if($non_nokia_widget)
       
   740 			  		{
       
   741 			  			$widget_uid = CWRT_WIDGET_UI_NON_NOKIA_UID;
       
   742 			  		}
       
   743 			  		else
       
   744 			  		{
       
   745 			      	$widget_uid = CWRT_WIDGET_UI_UID;
       
   746 			      }
       
   747             
       
   748             # NOKIA:sharedlibrary check
       
   749             if($isSharedWidget)
       
   750             {
       
   751                 $dataDir = fixFilename(catfile($self->destLocation($drive), 'private', sprintf("%08X", $widget_uid),"data","lib",$sharedFolderName));
       
   752             }
       
   753             else
       
   754             {
       
   755                 #in case of WGT copy .mbm to \epoc32\winscw\C\private\200267c0\data\hash<BundleId>\
       
   756                 $dataDir = fixFilename(catfile($self->destLocation($drive), 'private', sprintf("%08X", $widget_uid),"data", $hashval));
       
   757             }
       
   758             mkpath $dataDir;
       
   759             $destFile = catfile($dataDir,$mbmName);
       
   760         }
       
   761         else
       
   762         {
       
   763            $destFile = catfile($dir, $root, $mbmName);
       
   764         }
       
   765     		# Exclude securewidget from making a mbm file
       
   766 			if (!$self->{'secure'}{lc $filename}){
       
   767             print "Copying $mbm to $destFile\n" if $self->{args}->{'debug'};
       
   768             copy $mbm, $destFile or die "Failed to copy $mbm to $destFile: $!";
       
   769             $self->addToRomList($drive, $destFile);
       
   770           	}
       
   771         }
       
   772         
       
   773     # Remember the data for the registry
       
   774     if( $w3c_widget )
       
   775       {
       
   776       push @installedCWRTProps, $widgetdata;
       
   777       }
       
   778     else
       
   779       {
       
   780 	    if (!$self->{'secure'}{lc $filename}){
       
   781       		push @installedProps, $widgetdata;
       
   782       	}
       
   783       }
       
   784 
       
   785     if (!$debug)
       
   786       {
       
   787       # Perl v5.6 can't delete files with unicode in their name on Windows
       
   788       if ($] < 5.008 && $^O =~ /MSWin32/)
       
   789         {
       
   790         system("rmdir /s /q $tempdir");
       
   791         }
       
   792       else
       
   793         {
       
   794         rmtree $tempdir;
       
   795         }
       
   796       }
       
   797     #Generate the secsession for .wgt widgets
       
   798     if( $w3c_widget ) 
       
   799       {
       
   800       $self->addToRomList($drive, $self->makeSecSession($drive));
       
   801       }
       
   802   }
       
   803 
       
   804   my $cwrtdbPath = catfile($self->destLocation($drive), CWRT_WEBAPP_REGISTRY);
       
   805   $self->addToRomList($drive, $cwrtdbPath);
       
   806   
       
   807   # Generate the registry and IBY file
       
   808   $self->addToRomList($drive, $self->makeRegistry($drive, \@installedProps, 0));
       
   809   $self->addToRomList($drive, $self->makeRegistry($drive, \@installedCWRTProps, 1));
       
   810     
       
   811 
       
   812   print "\n\n %%%%%          WIDGET PRE-INSTALLATION completed for Drive $drive          %%%%% \n\n";
       
   813   }
       
   814 
       
   815 sub un7zipWidget
       
   816   {
       
   817   my ( $self, $filename, $tempdir ) = @_;
       
   818 
       
   819   # Unzip the file
       
   820   die "Can't find 7z.exe tool on PATH." if !findCmd('7z.exe');
       
   821   die "Failed to extract widget contents using 7zip: $!" if (system("7z x -aoa -o$tempdir \"$filename\" >nul 2>&1") != 0);
       
   822   }
       
   823 
       
   824 sub unzipWidget
       
   825   {
       
   826   my ( $self, $filename, $tempdir ) = @_;
       
   827 
       
   828   # Unzip the file
       
   829   die "Can't find unzip.exe tool on PATH." if !findCmd('unzip.exe');
       
   830   die "Failed to extract widget contents using zip: $!" if (system("unzip.exe \"$filename\" -d $tempdir >nul 2>&1") != 0);
       
   831   }
       
   832 
       
   833 # Recursively get list of files in a folder
       
   834 sub getFiles
       
   835   {
       
   836   my ( $self, $tempdir ) = @_;
       
   837 
       
   838   my $root = '.';
       
   839   my @extracted;
       
   840   my $size =0;
       
   841   
       
   842   my @dirs = '.';
       
   843   foreach my $dir ( @dirs )
       
   844     {
       
   845     opendir DIR, catfile($tempdir, $dir) or die "Failed to opendir $dir: $!";
       
   846     foreach ( grep !/^\.{1,2}$/, readdir DIR )
       
   847       {
       
   848       my $name = catfile($dir, $_);
       
   849       my $fullname = catfile($tempdir, $name);
       
   850       if (-d $fullname)
       
   851         {
       
   852         push @dirs, $name;
       
   853         }
       
   854       else
       
   855         {
       
   856         # Remember total size for later
       
   857         if (-e $fullname)
       
   858           {
       
   859           push @extracted, $name;
       
   860           print "Extracted: $name\n" if $self->{args}->{'debug'};
       
   861           $size += -s $fullname;
       
   862 
       
   863           # Get root
       
   864           if ($name =~ /info.plist$/i && $name =~ /^([^\/\\]+)[\/\\]/)
       
   865             {
       
   866             $root = $1;
       
   867             }
       
   868           }
       
   869         else
       
   870           {
       
   871           warn "WARNING: Failed to find extracted file $fullname";
       
   872           }
       
   873         }
       
   874       }
       
   875     closedir DIR;
       
   876     }
       
   877 
       
   878   return ( $root, \@extracted, $size );
       
   879   }
       
   880 
       
   881 ## see http://www.loc.gov/standards/iso639-2/php/code_list.php
       
   882 ## see http://www.loc.gov/standards/iso639-2/faq.html#2
       
   883 sub getLocalisedStringByLangCode
       
   884   {
       
   885   my ( $self, $dir, $strName, $langCode ) = @_;
       
   886   my $localised;
       
   887 
       
   888   # Generate the name of the file containing localised strings for this language
       
   889   my $locfile = catfile($dir, "$langCode.lproj", "InfoPlist.strings");
       
   890   if (-e $locfile)
       
   891         {
       
   892     # Open the file
       
   893     print "Found $langCode language translations in $locfile\n" if $verbose;
       
   894     open LOC, $locfile or die "Failed to open $locfile: $!";
       
   895 
       
   896     # Get the byte order mark from the start of the file
       
   897     my $bom;
       
   898     $bom = unpack("S", $bom) if (read(LOC, $bom, 2) == 2);
       
   899     if ($bom)
       
   900       {
       
   901       if ($bom == 0xEFBB)
       
   902         {
       
   903         # Skip utf8 bom
       
   904         seek LOC, 3, 0;
       
   905         }
       
   906       elsif ($bom != 0xFFFE && $bom != 0xFEFF)
       
   907         {
       
   908         seek LOC, 0, 0;
       
   909         undef $bom;
       
   910         }
       
   911       }
       
   912     else
       
   913       {
       
   914       # go back to start of file if no bom
       
   915       seek LOC, 0, 0;
       
   916       undef $bom;
       
   917       }
       
   918 
       
   919     while(my $line = <LOC>)
       
   920       {
       
   921       # Do unicode conversion
       
   922       my $ustr;
       
   923       if ($bom)
       
   924         {
       
   925         $ustr = utf16($line);
       
   926         $ustr->byteswap if $bom != 0xFFFE;
       
   927         }
       
   928       else
       
   929         {
       
   930         $ustr = utf8($line);
       
   931         }
       
   932 
       
   933       # Find the string we're looking for
       
   934       if ($ustr->utf8 =~ /(?:^|\s)$strName\s*=\s*\"([^\"]*)\"/)
       
   935         {
       
   936         print "\t...$strName => $1\n" if $debug;
       
   937         $localised = utf8($1);
       
   938         }
       
   939       }
       
   940     close LOC;
       
   941     }
       
   942     return $localised;
       
   943   }
       
   944 
       
   945 # Get localised version of strings if they exist
       
   946 sub getLocalisedStrings
       
   947   {
       
   948   my ( $self, $dir, $strName ) = @_;
       
   949   return if (!$self->{'langmapping'});
       
   950 
       
   951   # Iterate through all the languages we know about
       
   952   my %result;
       
   953   for(my $i = 0; $i < scalar(@{ $self->{'langmapping'}->{LangID} }); $i++)
       
   954     {
       
   955     my ( $langid, $langname ) = ( $self->{'langmapping'}->{LangID}->[$i], $self->{'langmapping'}->{LangDir}->[$i] );
       
   956 
       
   957     my $localised = $self->getLocalisedStringByLangCode($dir, $strName, $langname);
       
   958     $result{$langid} = $localised if $localised;
       
   959     }
       
   960 
       
   961   return \%result if keys %result;
       
   962   }
       
   963 
       
   964 # Find and execute a command
       
   965 sub findCmd
       
   966   {
       
   967   my $cmd = shift;
       
   968   return fixFilename("./$cmd") if -e $cmd;
       
   969 
       
   970   # PATH separator differs on Windows and Linux
       
   971   my $sep = $^O =~ /MSWin32/ ? ';' : ':';
       
   972 
       
   973   # Search each entry in the PATH
       
   974   my @paths = split /$sep/, $ENV{PATH};
       
   975   push @paths, dirname($0);
       
   976   foreach my $path ( @paths )
       
   977     {
       
   978     my $fullcmd = fixFilename(catfile($path, $cmd));
       
   979     return $fullcmd if -e $fullcmd;
       
   980     }
       
   981   }
       
   982 
       
   983 # Make INI file describing widget - this is passed to widgetregfiles.exe
       
   984 sub makeIni
       
   985   {
       
   986   my ( $self, $data, $file ) = @_;
       
   987   open INI, ">$file" or die "Failed to open $file for writing: $!";
       
   988   binmode INI, ":utf8" if $] >= 5.008;
       
   989 
       
   990   # Get directory where mbm should go
       
   991   my $dir = $self->regFileName($data->{'DriveName'});
       
   992 
       
   993   print INI "[app_registration_info]\n";
       
   994   print INI sprintf("uid=%08x\n", $data->{'Uid'});
       
   995   print INI "app_file=$data->{'MainHTML'}\n";
       
   996   print INI "caption=$data->{'BundleDisplayName'}\n";
       
   997   print INI "drive_name=$data->{'DriveName'}\n";
       
   998   print INI "results_dir=$dir\n";
       
   999   
       
  1000   if( $w3c_widget )
       
  1001   {
       
  1002     print INI "app_type=200267DC\n";
       
  1003     print " WGT Widget:: app_type added to ini of widgetregfiles.exe \n" if $debug;
       
  1004   }
       
  1005   
       
  1006 
       
  1007   # Add language stuff if we have the mapping
       
  1008   if ($data->{'LocBundleDisplayName'})
       
  1009     {
       
  1010     my @langList;
       
  1011     foreach my $langid ( sort { $a <=> $b } keys %{ $data->{'LocBundleDisplayName'} } )
       
  1012       {
       
  1013       my $symid = sprintf("%02d", $langid);
       
  1014       push @langList, $symid;
       
  1015       print INI "caption$symid=", $data->{'LocBundleDisplayName'}->{$langid}->utf8, "\n";
       
  1016       }
       
  1017     print INI "languages=", join(' ', @langList), "\n";
       
  1018     }
       
  1019 
       
  1020   close INI;
       
  1021   convert2Unicode($file);
       
  1022   }
       
  1023 
       
  1024  sub findfreeUid
       
  1025   {
       
  1026   my ( $self, $data ) = @_;
       
  1027   my $appfile = lc $data->{'MainHTML'};
       
  1028   my $uid;
       
  1029   my $size;
       
  1030     if($w3c_widget)     #CWRT Widget
       
  1031     {
       
  1032       # pick the next free CWRT Internal UID
       
  1033       if(isInternal($data->{'DriveName'}))
       
  1034       {
       
  1035         print "\nInternal CWRT UID";
       
  1036         $size = scalar @staticUidCwrtIntList;
       
  1037         print " Static UID :: @staticUidCwrtIntList Length -- $size \n" if($size);
       
  1038         for(my $i=0; $i<$size; $i++)
       
  1039         {
       
  1040 		  #skip looping if freeUid found
       
  1041           if( $self->{'freeuidcwrtint'} lt $staticUidCwrtIntList[$i] ) {last};
       
  1042           
       
  1043           if($self->{'freeuidcwrtint'} == $staticUidCwrtIntList[$i]) 
       
  1044           { 
       
  1045             $self->{'freeuidcwrtint'}++; 
       
  1046           }
       
  1047         }
       
  1048         $uid = $self->{'freeuidcwrtint'}++;   # Assign and then set next free UID
       
  1049       } 
       
  1050       else
       
  1051       {
       
  1052         # pick the next free CWRT External UID
       
  1053         print "\nExternal CWRT UID ";
       
  1054         $size = scalar @staticUidCwrtExtList;
       
  1055         print "Static UID :: @staticUidCwrtExtList Length -- $size \n";
       
  1056         
       
  1057         for(my $i=0; $i<$size; $i++)
       
  1058         {
       
  1059           if( $self->{'freeuidcwrtext'} lt $staticUidCwrtExtList[$i] ) {last};
       
  1060           
       
  1061           if($self->{'freeuidcwrtext'} == $staticUidCwrtExtList[$i]) 
       
  1062           { 
       
  1063             $self->{'freeuidcwrtext'}++; 
       
  1064           }
       
  1065         }
       
  1066         $uid = $self->{'freeuidcwrtext'}++;   # Assign and then set next free UID
       
  1067       }
       
  1068     }
       
  1069     else      #WRT widget
       
  1070     {
       
  1071       # pick the next free WRT Internal UID
       
  1072       if(isInternal($data->{'DriveName'}))
       
  1073       {
       
  1074         # pick the next free CWRT Internal UID
       
  1075         if(isInternal($data->{'DriveName'}))
       
  1076         {
       
  1077           print "\nInternal WRT UID ";
       
  1078           $size = scalar @staticUidWrtIntList;
       
  1079           print " STATIC UID :: @staticUidWrtIntList Length -- $size\n";
       
  1080                  
       
  1081           for(my $i=0; $i<$size; $i++)
       
  1082           {
       
  1083             if( $self->{'freeuidwrtint'} lt $staticUidWrtIntList[$i] ) {last};
       
  1084             
       
  1085             if($self->{'freeuidwrtint'} == $staticUidWrtIntList[$i]) 
       
  1086             { 
       
  1087               $self->{'freeuidwrtint'}++; 
       
  1088             }
       
  1089           }
       
  1090           $uid = $self->{'freeuidwrtint'}++;   # Assign and then set next free UID
       
  1091         }
       
  1092       }
       
  1093       else
       
  1094       {
       
  1095         # pick the next free WRT External UID
       
  1096         print "\nExternal WRT UID ";
       
  1097         $size = scalar @staticUidWrtExtList;
       
  1098         print "STATIC UID :: @staticUidWrtExtList Length -- $size\n";
       
  1099         
       
  1100         for(my $i=0; $i<$size; $i++)
       
  1101         {
       
  1102           if( $self->{'freeuidwrtext'} lt $staticUidWrtExtList[$i] ) {last};
       
  1103           
       
  1104           if($self->{'freeuidwrtext'} == $staticUidWrtExtList[$i]) 
       
  1105           { 
       
  1106             $self->{'freeuidwrtext'}++; 
       
  1107           }
       
  1108         }
       
  1109         $uid = $self->{'freeuidwrtext'}++;   # Assign and then set next free UID
       
  1110       }
       
  1111     }
       
  1112   print sprintf("Generated UID: hex->0x%08X dec->$uid\n \n",$uid);
       
  1113   return $uid;
       
  1114   }
       
  1115 
       
  1116 # Fix slash problems in a filename
       
  1117 sub fixFilename
       
  1118   {
       
  1119   my $filename = shift;
       
  1120   $filename =~ s/([\\\/])[\\\/]/$1/g;
       
  1121   return catfile(split(/[\\\/]/, $filename));
       
  1122   }
       
  1123 
       
  1124 # Get install location
       
  1125 sub destLocation
       
  1126   {
       
  1127   my ( $self, $drive ) = @_;
       
  1128   my $letter = uc(substr($drive, 0, 1));
       
  1129   
       
  1130   # Was any destination location specified in the config file?
       
  1131   if ($self->{destination} && $self->{destination}->{$letter})
       
  1132     {
       
  1133     return catfile($self->{'args'}->{'epocroot'}, $self->{destination}->{$letter});
       
  1134     }
       
  1135     
       
  1136   # No destination specified - use emulator location
       
  1137   return catfile($self->{'args'}->{'epocroot'}, $letter eq 'Z' ? ROM_DEST : sprintf(DRIVE_DEST, $letter));
       
  1138   }
       
  1139   
       
  1140 # Get the destination for REG/LOC/MBM file
       
  1141 sub regFileName
       
  1142   {
       
  1143   my ( $self, $drive, $filename ) = @_;
       
  1144   my $result = catfile($self->destLocation($drive), DESTINATION, $filename);
       
  1145   return fixFilename($result);
       
  1146   }
       
  1147 
       
  1148 # Widget install directory
       
  1149 sub installDir
       
  1150   {
       
  1151   my ( $self, $drive, $id ) = @_;
       
  1152   my $result ;
       
  1153   $hashval = hashpjw($id);
       
  1154   if( $w3c_widget )
       
  1155   {
       
  1156   	my $widget_uid;
       
  1157     if($non_nokia_widget)
       
  1158 	{
       
  1159 		$widget_uid = CWRT_WIDGET_UI_NON_NOKIA_UID;
       
  1160 	}
       
  1161 	else
       
  1162 	{
       
  1163 		$widget_uid = CWRT_WIDGET_UI_UID;
       
  1164 	}
       
  1165     if($isSharedLibrary)
       
  1166     {
       
  1167     	$result = catfile($self->destLocation($drive), 'private', sprintf("%08X", $widget_uid),"widgets_21D_4C7", "lib",$sharedFolderName);
       
  1168     }
       
  1169     else
       
  1170     {
       
  1171         $result = catfile($self->destLocation($drive), 'private', sprintf("%08X", $widget_uid),"widgets_21D_4C7", $hashval);
       
  1172     }
       
  1173   }
       
  1174   else
       
  1175       {
       
  1176 	  	if ($isSecureWidget){
       
  1177 	   		print "Installing secure WGZ Widget\n";
       
  1178 	    	$result = catfile($self->destLocation($drive), 'private', sprintf("%08x", SWIDGET_UI_UID), $id);
       
  1179 	  	} else {
       
  1180 	   		print "Installing WGZ Widget\n";
       
  1181         	$result = catfile($self->destLocation($drive), 'private', sprintf("%08x", WIDGET_UI_UID), $id);
       
  1182 	  	}
       
  1183       }    
       
  1184   return fixFilename($result);
       
  1185   }
       
  1186 
       
  1187 # Determines whether a drive should be considered internal or not
       
  1188 sub isInternal
       
  1189   {
       
  1190   my $drive = shift;
       
  1191   die "Invalid drive format: $drive" if $drive !~ /^[a-zA-Z]:/;
       
  1192   return 1 if $drive =~ /^[zcZC]/;
       
  1193   }
       
  1194 
       
  1195 # Parse these awful PLIST files
       
  1196 sub parsePList
       
  1197   {
       
  1198   my $file = shift;
       
  1199 
       
  1200   # Create parser object
       
  1201   our ($key, $val, $plisthash ) = ('', '', {});
       
  1202   my $parser = new XML::Parser;
       
  1203   $parser->setHandlers('Doctype' => \&docT, 'Start' => \&startH, 'End' => \&endH, 'Char' => \&dataH);
       
  1204 
       
  1205   # Parse the file
       
  1206   open XML, $file or die "Couldn't open $file";
       
  1207 
       
  1208   # Skip the UTF8 BOM - perl 5.6 can't handle it
       
  1209   my $bom;
       
  1210   read XML, $bom, 3;
       
  1211   $bom = join('', map(sprintf('%X', $_), unpack("CCC", $bom)));
       
  1212   print "Testing the following for BOM: $bom\n" if $debug;
       
  1213   seek(XML, 0, 0) if $bom ne 'EFBBBF';
       
  1214 
       
  1215   $parser->parse(*XML);
       
  1216   close XML;
       
  1217 
       
  1218   # Check required fields exist
       
  1219   die "Widget MainHTML unknown" if !$plisthash->{'MainHTML'};
       
  1220   die "Widget BundleIdentifier unknown" if !$plisthash->{'BundleIdentifier'};
       
  1221   die "Widget BundleDisplayName unknown" if !$plisthash->{'BundleDisplayName'};
       
  1222 
       
  1223   # Return result
       
  1224   return $plisthash;
       
  1225 
       
  1226   # Called on a start tag
       
  1227   sub startH
       
  1228     {
       
  1229     my ($p, $el, %atts) = @_;
       
  1230     undef $key if ($el =~ /^key$/i);
       
  1231     $val = '';
       
  1232     }
       
  1233 
       
  1234   # Receives document type
       
  1235   sub docT
       
  1236     {
       
  1237     my ($expat, $name, $sysid, $pubid, $internal ) = @_;
       
  1238     die "PLIST format looks wrong!" if lc($name) ne 'plist';
       
  1239     $plisthash->{'NokiaWidget'} = ( $pubid =~ m[^-//Nokia//DTD PLIST]i ) ? 1 : 0;
       
  1240     }
       
  1241 
       
  1242   # Receives character data
       
  1243   sub dataH
       
  1244     {
       
  1245     my ($p, $s) = @_;
       
  1246     $val .= $s;
       
  1247     }
       
  1248 
       
  1249   # Called on an end tag
       
  1250   sub endH
       
  1251     {
       
  1252     my ($p, $el) = @_;
       
  1253     if ($el =~ /^key$/i)
       
  1254       {
       
  1255       $key = $val;
       
  1256       }
       
  1257     elsif ($key)
       
  1258       {
       
  1259       $val = 1 if $el =~ /^true$/i;
       
  1260       $val = 0 if $el =~ /^false$/i;
       
  1261 
       
  1262       # Fix stuff so it's in the correct format
       
  1263       $key =~ s/^CF//;
       
  1264       $key = 'BundleIdentifier' if $key =~ /^Identifier$/i;
       
  1265       $key = 'BundleDisplayName' if $key =~ /^DisplayName$/i;
       
  1266       $key = 'BundleVersion' if $key =~ /^Version$/i;
       
  1267 
       
  1268       $plisthash->{$key} = $val;
       
  1269       undef $key;
       
  1270       }
       
  1271     $val = ''
       
  1272     }
       
  1273   }
       
  1274 
       
  1275 
       
  1276 sub parseConfXml
       
  1277   {
       
  1278     my ( $file , $language ) = @_;
       
  1279 
       
  1280   our ($key, $val, $plisthash, $localizationValue,$localizationIconValue, $lang,$langIcon) = ('', '', {}, '','', {},{});
       
  1281   our ($featureCount, $paramCount, $accessCount) = (1,1,1);
       
  1282   our ($attributeMap, $featureMap, $featureParamMap, $accessMap)=('','','','');
       
  1283   
       
  1284   # Create parser object
       
  1285   my $parser = new XML::Parser;
       
  1286   $parser->setHandlers( 'Start' => \&startC, 'End' => \&endC, 'Char' => \&dataC);
       
  1287    
       
  1288   # Parse the file
       
  1289   open XML,$file or die "Couldn't open $file";
       
  1290   # Skip the UTF8 BOM - perl 5.6 can't handle it
       
  1291   my $bom;
       
  1292   read XML, $bom, 3;
       
  1293   $bom = join('', map(sprintf('%X', $_), unpack("CCC", $bom)));
       
  1294   print "Testing the following for BOM: $bom\n" if $debug;
       
  1295   seek(XML, 0, 0) if $bom ne 'EFBBBF';
       
  1296     $plisthash->{'NokiaWidget'} = 2 ;
       
  1297     $plisthash->{'WidgetPackagingFormat'} = "w3c-partial-v1" ;
       
  1298   
       
  1299   $parser->parse(*XML);
       
  1300   close XML;
       
  1301 
       
  1302     if( $language )
       
  1303         {
       
  1304          if($lang->{$language})
       
  1305          { 
       
  1306           $plisthash->{'BundleDisplayName'} = $lang->{$language};
       
  1307          }
       
  1308          if($langIcon->{$language})
       
  1309          {
       
  1310           $plisthash->{'IconPath'} = $langIcon->{$language};
       
  1311          }
       
  1312         }
       
  1313   die "Widget BundleIdentifier unknown" if !$plisthash->{'BundleIdentifier'};
       
  1314   die "Widget BundleDisplayName unknown" if !$plisthash->{'BundleDisplayName'};
       
  1315   
       
  1316    $attributeMap = $attributeMap.WIDGET_NAME.KEY_VALUE_SEPERATOR.$plisthash->{'BundleDisplayName'}.KEY_VALUE_PAIR_SEPERATOR;
       
  1317 
       
  1318    if($non_nokia_widget)
       
  1319    {
       
  1320        $attributeMap = $attributeMap.WIDGET_PROCESSUID.KEY_VALUE_SEPERATOR."200267D6".KEY_VALUE_PAIR_SEPERATOR;
       
  1321    }
       
  1322    else
       
  1323    {
       
  1324        $attributeMap = $attributeMap.WIDGET_PROCESSUID.KEY_VALUE_SEPERATOR."200267C0".KEY_VALUE_PAIR_SEPERATOR;
       
  1325    }
       
  1326 
       
  1327     if($attributeMap)
       
  1328     {      
       
  1329         $plisthash->{'AttributeList'} = $attributeMap;
       
  1330         print "\nAttributeList::$plisthash->{'AttributeList'}\n"
       
  1331     }
       
  1332 
       
  1333   # Return result
       
  1334   return $plisthash;
       
  1335 
       
  1336   # Called on a start tag
       
  1337   sub startC
       
  1338     {
       
  1339     my ($p, $el, %atts) = @_;
       
  1340     
       
  1341     if($el eq "widget")
       
  1342         {
       
  1343          if ( $atts{"id"} )
       
  1344              {
       
  1345             $plisthash->{'BundleIdentifier'} = $atts{"id"};
       
  1346             $attributeMap = $attributeMap.WIDGET_ID.KEY_VALUE_SEPERATOR.$atts{"id"}.KEY_VALUE_PAIR_SEPERATOR;
       
  1347             
       
  1348              }
       
  1349          if ( $atts{"version"} )
       
  1350              {
       
  1351             $plisthash->{'BundleVersion'} = $atts{"version"};
       
  1352             $attributeMap = $attributeMap.WIDGET_VERSION.KEY_VALUE_SEPERATOR.$atts{"version"}.KEY_VALUE_PAIR_SEPERATOR;
       
  1353              }
       
  1354          if ( $atts{"viewmodes"} && $atts{"viewmodes"} eq "all" )
       
  1355              {
       
  1356             $plisthash->{'MiniViewEnabled'} = 1;
       
  1357              }
       
  1358          $attributeMap = $attributeMap.WIDGET_HEIGHT.KEY_VALUE_SEPERATOR.$atts{"height"}.KEY_VALUE_PAIR_SEPERATOR;
       
  1359          $attributeMap = $attributeMap.WIDGET_WIDTH.KEY_VALUE_SEPERATOR.$atts{"width"}.KEY_VALUE_PAIR_SEPERATOR;
       
  1360         }
       
  1361       elsif ($el eq "icon")
       
  1362           {
       
  1363            if ( $atts{"xml:lang"} )
       
  1364              {
       
  1365               $localizationIconValue = lc($atts{"xml:lang"}) ;
       
  1366              }
       
  1367            if ( $atts{"src"} )
       
  1368              {
       
  1369             $plisthash->{'IconPath'} = $atts{"src"};
       
  1370                  }
       
  1371           }
       
  1372       elsif ($el eq "content")
       
  1373           {
       
  1374            $attributeMap = $attributeMap.WIDGET_CONTENT.KEY_VALUE_SEPERATOR.KEY_VALUE_PAIR_SEPERATOR;	
       
  1375            if ( $atts{"src"} )
       
  1376              {
       
  1377             $plisthash->{'MainHTML'} = $atts{"src"};
       
  1378             $attributeMap = $attributeMap.WIDGET_CONTENT.KEY_ATTR_SEPERATOR."src".KEY_VALUE_SEPERATOR.$atts{"src"}.KEY_VALUE_PAIR_SEPERATOR;
       
  1379              }
       
  1380           }
       
  1381       elsif ($el eq "name")
       
  1382           {
       
  1383            if ( $atts{"xml:lang"} )
       
  1384              {
       
  1385               $localizationValue = lc($atts{"xml:lang"}) ;
       
  1386              }
       
  1387           }
       
  1388       elsif ($el eq "feature")
       
  1389           {
       
  1390            $featureMap = WIDGET_FEATURE . $featureCount;
       
  1391            $attributeMap = $attributeMap.$featureMap.KEY_VALUE_SEPERATOR.KEY_VALUE_PAIR_SEPERATOR;
       
  1392            
       
  1393            if ( $atts{"name"} )
       
  1394              {
       
  1395               $attributeMap = $attributeMap.$featureMap.KEY_ATTR_SEPERATOR."name".KEY_VALUE_SEPERATOR.$atts{"name"}.KEY_VALUE_PAIR_SEPERATOR;
       
  1396               my $jilFeature = "http://jil.org/jil";
       
  1397               if($atts{"name"}=~ m/^$jilFeature/i)
       
  1398               {
       
  1399                 $plisthash->{'WidgetPackagingFormat'} = "jil";
       
  1400               }
       
  1401              }
       
  1402          if ( $atts{"required"} )
       
  1403              {
       
  1404               $attributeMap = $attributeMap.$featureMap.KEY_ATTR_SEPERATOR."required".KEY_VALUE_SEPERATOR.$atts{"required"}.KEY_VALUE_PAIR_SEPERATOR;
       
  1405              }
       
  1406          }
       
  1407        elsif($el eq "param")
       
  1408           {
       
  1409               $featureParamMap = $featureMap. WIDGET_FEATURE_PARAM . $paramCount;
       
  1410               $attributeMap = $attributeMap.$featureParamMap.KEY_VALUE_SEPERATOR.KEY_VALUE_PAIR_SEPERATOR;
       
  1411               if ($atts{"name"}) 
       
  1412               {
       
  1413                   $attributeMap = $attributeMap.$featureParamMap.KEY_ATTR_SEPERATOR."name".KEY_VALUE_SEPERATOR.$atts{"name"}.KEY_VALUE_PAIR_SEPERATOR;
       
  1414               }
       
  1415               if ($atts{"value"})
       
  1416               {
       
  1417                   $attributeMap = $attributeMap.$featureParamMap.KEY_ATTR_SEPERATOR."value".KEY_VALUE_SEPERATOR.$atts{"value"}.KEY_VALUE_PAIR_SEPERATOR;
       
  1418               }
       
  1419           }
       
  1420        elsif ($el eq "access" || $el eq "jil:access")
       
  1421           {
       
  1422               $accessMap = WIDGET_ACCESS . $accessCount;
       
  1423               $attributeMap = $attributeMap.$accessMap.KEY_VALUE_SEPERATOR.KEY_VALUE_PAIR_SEPERATOR;
       
  1424            
       
  1425               if ( $atts{"network"} )
       
  1426              {
       
  1427                 $attributeMap = $attributeMap.$accessMap.KEY_ATTR_SEPERATOR."network".KEY_VALUE_SEPERATOR.$atts{"network"}.KEY_VALUE_PAIR_SEPERATOR;
       
  1428              }
       
  1429             if ( $atts{"remotescripts"} )
       
  1430              {
       
  1431                 $attributeMap = $attributeMap.$accessMap.KEY_ATTR_SEPERATOR."remotescripts".KEY_VALUE_SEPERATOR.$atts{"remotescripts"}.KEY_VALUE_PAIR_SEPERATOR;
       
  1432              }
       
  1433              if ( $atts{"localfs"} )
       
  1434              {
       
  1435                 $attributeMap = $attributeMap.$accessMap.KEY_ATTR_SEPERATOR."localfs".KEY_VALUE_SEPERATOR.$atts{"localfs"}.KEY_VALUE_PAIR_SEPERATOR;
       
  1436              }
       
  1437              if ( $atts{"origin"} )
       
  1438              {
       
  1439                 $attributeMap = $attributeMap.$accessMap.KEY_ATTR_SEPERATOR."origin".KEY_VALUE_SEPERATOR.$atts{"origin"}.KEY_VALUE_PAIR_SEPERATOR;
       
  1440              }
       
  1441              if ( $atts{"subdomains"} )
       
  1442              {
       
  1443                 $attributeMap = $attributeMap.$accessMap. KEY_ATTR_SEPERATOR."subdomains".KEY_VALUE_SEPERATOR.$atts{"subdomains"}.KEY_VALUE_PAIR_SEPERATOR;
       
  1444              }
       
  1445         }
       
  1446         elsif ($el eq "NOKIA:sharedlibrary")
       
  1447         {
       
  1448             print " \n\n ^^^^^^^^^^^^^^^^^^^^^^^NOKIA:sharedlibrary ^^^^^^^^^^^^^^^^^^^^ \n\n";
       
  1449             $isSharedLibrary = 1;
       
  1450             $plisthash->{'WidgetPackagingFormat'} = "shared-library";
       
  1451             $attributeMap = $attributeMap.WIDGET_NOKIA_SHAREDLIB.KEY_VALUE_SEPERATOR.KEY_VALUE_PAIR_SEPERATOR;
       
  1452         }
       
  1453      $val = '';    
       
  1454      }
       
  1455     
       
  1456 sub docC{}
       
  1457 # Receives character data
       
  1458   sub dataC
       
  1459     {
       
  1460     my ($p, $s) = @_;
       
  1461     $val .= $s;
       
  1462     }
       
  1463 
       
  1464   # Called on an end tag
       
  1465   sub endC
       
  1466     {
       
  1467     my ($p, $el) = @_;
       
  1468     if ($el eq "name")
       
  1469         {
       
  1470        if( $localizationValue )
       
  1471            {
       
  1472             chomp($val);
       
  1473             $lang->{$localizationValue} = $val;
       
  1474             $localizationValue = '';
       
  1475              }
       
  1476          else
       
  1477              {
       
  1478               chomp($val);
       
  1479               $plisthash->{'BundleDisplayName'} = $val;
       
  1480              }   
       
  1481       }
       
  1482       elsif ($el eq "icon")
       
  1483       {
       
  1484         if( $localizationIconValue )
       
  1485            {
       
  1486             $langIcon->{$localizationIconValue} = $plisthash->{'IconPath'};
       
  1487             print "\n %%%%%%%%%%%  $localizationIconValue  :: $plisthash->{'IconPath'}%%%%%%%%%%%%%\n";
       
  1488             $localizationIconValue = '';
       
  1489            }
       
  1490       }
       
  1491     elsif($el eq "feature")
       
  1492       {
       
  1493           $featureCount++;
       
  1494           $paramCount = 0;
       
  1495       }
       
  1496     elsif($el eq "param")
       
  1497       {
       
  1498           $paramCount++;
       
  1499       }
       
  1500       elsif($el eq "access" || $el eq "jil:access")
       
  1501       {
       
  1502           $accessCount++;
       
  1503       } 
       
  1504       elsif ($el eq "NOKIA:folder")
       
  1505         {
       
  1506             chomp($val);
       
  1507             $sharedFolderName = $val;
       
  1508             $attributeMap = $attributeMap.WIDGET_NOKIA_SHAREDLIB_FOLDER.KEY_VALUE_SEPERATOR.$sharedFolderName.KEY_VALUE_PAIR_SEPERATOR;
       
  1509         }
       
  1510     elsif ($el eq "NOKIA:widget")
       
  1511         {
       
  1512             chomp($val);
       
  1513             if( lc($val) eq "true" )
       
  1514             {
       
  1515                 $isSharedWidget = 1;
       
  1516                 $plisthash->{'WidgetPackagingFormat'} = "w3c-partial-v1";
       
  1517             }
       
  1518             $attributeMap = $attributeMap.WIDGET_NOKIA_SHAREDLIB_WIDGET.KEY_VALUE_SEPERATOR.$val.KEY_VALUE_PAIR_SEPERATOR;
       
  1519         }
       
  1520     elsif ($el eq "NOKIA:icon")
       
  1521         {
       
  1522             chomp($val);
       
  1523             if( lc($val) eq "true" )
       
  1524             {
       
  1525                 $isSharedIcon = 1;
       
  1526             }
       
  1527             $attributeMap = $attributeMap.WIDGET_NOKIA_SHAREDLIB_ICON.KEY_VALUE_SEPERATOR.$val.KEY_VALUE_PAIR_SEPERATOR;
       
  1528         }
       
  1529     $val = ''
       
  1530     }
       
  1531 
       
  1532   }
       
  1533 
       
  1534 
       
  1535 # Stores the details of files to be added to "rom"
       
  1536 sub addToRomList
       
  1537   {
       
  1538   my ( $self, $drive, $file, $localised ) = @_;
       
  1539   $file = fixFilename($file);
       
  1540 
       
  1541   # All files should be under epoc32 somewhere - need to drop a bit of the path for the rom destination
       
  1542   my $localpath = $self->destLocation($drive);
       
  1543 
       
  1544   my $dest = fixFilename($file);
       
  1545   $dest =~ s/^\Q$localpath\E//i;
       
  1546 
       
  1547   # Add the file to the list for the rom
       
  1548   # It may be localised - in which it'll be put in a different IBY file
       
  1549   $localised = $localised ? '_rsc' : '';
       
  1550   $self->{"installedFiles${localised}"}->{$drive}->{$file} = $dest;
       
  1551   }
       
  1552 
       
  1553 # Make the IBY file
       
  1554 sub makeIBY
       
  1555   {
       
  1556   my ( $self, $drive, $localised ) = @_;
       
  1557 
       
  1558   # Generate the file name for the IBY file
       
  1559   $localised = $localised ? '_rsc' : '';
       
  1560   my $name = $drive =~ /^[zZ]/ ? "preinstalledwidgets${localised}.iby" : sprintf("preinstalledwidgets_drive%s${localised}.iby", substr($drive, 0, 1));
       
  1561   my $iby = fixFilename(catfile($self->{'args'}->{'epocroot'}, 'epoc32', 'rom', 'include', $name));
       
  1562   print "Generating: $iby\n";
       
  1563 
       
  1564   mkpath dirname($iby);
       
  1565   open IBY, ">$iby" or die "Failed to open $iby for writing: $!";
       
  1566   $name =~ s/\./_/g; $name = uc($name);
       
  1567   print IBY "// GENERATED FILE: EDIT WITH CARE\n\#ifndef __${name}__\n\#define __${name}__\n\n";
       
  1568   foreach my $file ( sort keys %{ $self->{"installedFiles${localised}"}->{$drive} } )
       
  1569     {
       
  1570     my $dest = $self->{"installedFiles${localised}"}->{$drive}->{$file};
       
  1571 
       
  1572     # Quote filenames as they may contain spaces!
       
  1573     print IBY "data=\"$file\"\t\"$dest\"\n";
       
  1574     }
       
  1575   print IBY "\#endif\n";
       
  1576   close IBY;
       
  1577   }
       
  1578 
       
  1579 # Unregister (with Apparc) existing Widgets
       
  1580 sub unregisterWidgets
       
  1581 {
       
  1582   my ( $self, $drive ) = @_;
       
  1583     
       
  1584     my $registry = fixFilename(catfile($self->destLocation($drive), WIDGET_REGISTRY));
       
  1585   # If the WRT registry already exists, remove apparc registry info for those widgets
       
  1586   # This should avoid problems with unregistered widget icons in the emulator?
       
  1587     if (-e $registry)
       
  1588     {
       
  1589         print("\n			UNREGISTERING WGZ WIDGETS       \n");
       
  1590         
       
  1591       my $ref = XMLin($registry, 'forcearray' => [ 'entry' ], 'keyattr' => { 'prop' => 'content' } );
       
  1592     foreach my $entry ( @{ $ref->{entry} } )
       
  1593       {
       
  1594       my $uid = $entry->{prop}->{Uid}->{val}->{content};
       
  1595 
       
  1596       print "Unregistering existing Widget: $entry->{prop}->{BundleIdentifier}->{val}->{content}\n" if $verbose;
       
  1597       my $dest = $self->regFileName($drive);
       
  1598       my $mbm = catfile($dest, sprintf("[%08x].mbm", $uid));
       
  1599       my ( $reg, $loc ) = ( catfile($dest, sprintf("%08x_reg.rsc", $uid)), catfile($dest, sprintf("%08x_loc.rsc", $uid)) );
       
  1600       unlink $mbm, $reg, $loc;
       
  1601     
       
  1602       # We also have to delete the widget directory otherwise it'll be re-registered
       
  1603       my $id = $entry->{prop}->{BundleIdentifier}->{val}->{content};
       
  1604       $w3c_widget = 0;
       
  1605       my $dir = $self->installDir($drive, $id);
       
  1606       rmtree $dir;
       
  1607       }
       
  1608     }
       
  1609     
       
  1610   $registry = fixFilename(catfile($self->destLocation($drive), CWRT_WIDGET_REGISTRY));
       
  1611 
       
  1612   # If the CWRT registry already exists, remove apparc registry info for those widgets
       
  1613   # This should avoid problems with unregistered widget icons in the emulator?
       
  1614   if (-e $registry)
       
  1615     {
       
  1616         print("\n			UNREGISTERING WGT WIDGETS       \n");
       
  1617         
       
  1618           my $ref = XMLin($registry, 'forcearray' => [ 'entry' ], 'keyattr' => { 'prop' => 'content' } );
       
  1619         foreach my $entry ( @{ $ref->{entry} } )
       
  1620       {
       
  1621           my $uid = $entry->{prop}->{Uid}->{val}->{content};
       
  1622     
       
  1623           print "Unregistering existing Widget: $entry->{prop}->{BundleIdentifier}->{val}->{content}\n" if $verbose;
       
  1624           my $dest = $self->regFileName($drive);
       
  1625             my $mbm = catfile($dest, sprintf("[%08x].mbm", $uid));
       
  1626           my ( $reg, $loc ) = ( catfile($dest, sprintf("%08x_reg.rsc", $uid)), catfile($dest, sprintf("%08x_loc.rsc", $uid)) );
       
  1627           unlink $mbm, $reg, $loc;
       
  1628        
       
  1629           # We also have to delete the widget directory otherwise it'll be re-registered
       
  1630           my $id = $entry->{prop}->{BundleIdentifier}->{val}->{content};
       
  1631           print " Unregistering $id ";
       
  1632           my $basepath = $entry->{prop}->{BasePath}->{val}->{content};
       
  1633           $w3c_widget = 1;
       
  1634           my $sharedLib = "lib";          #BasePath will have lib only if the widget is shared Library
       
  1635           
       
  1636           if($basepath =~ m/$sharedLib/)
       
  1637           {
       
  1638               $isSharedLibrary = 1;
       
  1639           }
       
  1640           
       
  1641           if($basepath =~ m/\\200267d6\\/i)
       
  1642           {
       
  1643           	$non_nokia_widget = 1;	
       
  1644           }
       
  1645            #sharedFolderName TBD
       
  1646           my $dir = $self->installDir($drive, $id);
       
  1647           rmtree $dir;
       
  1648                 
       
  1649           print("BasePath:$basepath \nIs Non-Nokia? $non_nokia_widget		Is SharedLibrary? $isSharedLibrary \nDirectory:$dir \n");
       
  1650     
       
  1651             $dir =~ s/widgets_21D_4C7/data/;
       
  1652           rmtree $dir;
       
  1653         }
       
  1654     }
       
  1655     #delete CWRT webapp DB if exists
       
  1656     my $cwrtdbPath = catfile($self->destLocation($drive), CWRT_WEBAPP_REGISTRY);
       
  1657     if($cwrtdbPath)
       
  1658     {
       
  1659     	print "Deleting CWRT_WEBAPP_REGISTRY \n";
       
  1660     	rmtree $cwrtdbPath;
       
  1661     }
       
  1662   }
       
  1663 
       
  1664 # Make the registry
       
  1665 sub makeRegistry
       
  1666   {
       
  1667   my ($self, $drive, $installed, $w3c) = @_;
       
  1668   
       
  1669   my ($registry);
       
  1670   if($w3c)
       
  1671     {
       
  1672     $registry = fixFilename(catfile($self->destLocation($drive), CWRT_WIDGET_REGISTRY));
       
  1673     }
       
  1674   else
       
  1675     {
       
  1676     $registry = fixFilename(catfile($self->destLocation($drive), WIDGET_REGISTRY));
       
  1677     }
       
  1678     
       
  1679   print "\nGenerating: $registry\n";
       
  1680 
       
  1681   # Write the file
       
  1682   mkpath dirname($registry);
       
  1683   open OUT, ">$registry" or die "Failed to open WidgetEntryStore.xml: $!";
       
  1684 
       
  1685   print OUT "<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"yes\" ?>\n<widgetregistry>\n";
       
  1686   binmode OUT, ":utf8" if $] >= 5.008;
       
  1687   foreach my $pList ( @$installed )
       
  1688     {
       
  1689     $self->dumpPList(\*OUT, $pList, $w3c);
       
  1690     }
       
  1691   print OUT "</widgetregistry>\n";
       
  1692   close OUT;
       
  1693 
       
  1694   # Convert the file to unicode
       
  1695   convert2Unicode($registry);
       
  1696 
       
  1697   # Return the generated file
       
  1698   return $registry;
       
  1699   }
       
  1700 
       
  1701 # Converts a file to Unicode
       
  1702 sub convert2Unicode
       
  1703   {
       
  1704   my $file = shift;
       
  1705 
       
  1706   my @lines;
       
  1707   open IN, $file or die "Failed to open $file: $!";
       
  1708   binmode IN;
       
  1709   while(<IN>)
       
  1710     {
       
  1711     my $u = utf8($_);
       
  1712     $u->byteswap;
       
  1713     push @lines, $u->utf16;
       
  1714     }
       
  1715   close IN;
       
  1716 
       
  1717   open OUT, ">$file" or die "Failed to open $file for writing: $!";
       
  1718   binmode OUT;
       
  1719   print OUT pack("CC", 0xff, 0xfe);
       
  1720   print OUT @lines;
       
  1721   close OUT;
       
  1722   }
       
  1723 
       
  1724 sub hashpjw {
       
  1725   my $s = shift;
       
  1726   my $hashval = 0;
       
  1727   my $g;
       
  1728 
       
  1729   for ( split //, $s ) {
       
  1730     $hashval = ( $hashval << 4 ) + ord $_; 
       
  1731     
       
  1732     if ($g = $hashval & 0xf0000000) {
       
  1733       $hashval ^= $g >> 23;
       
  1734     }
       
  1735     $hashval &= ~$g;
       
  1736   }
       
  1737   #print "$hashval \n";
       
  1738   return $hashval;
       
  1739 } 
       
  1740 
       
  1741 # Dumps a single PList hash object
       
  1742 sub dumpPList
       
  1743   {
       
  1744   my ($self, $fh, $data, $w3c) = @_;
       
  1745   my @regProperties = (
       
  1746     [ 'PropertyListVersion', 'int' ],
       
  1747     [ 'BundleIdentifier', 'string' ],
       
  1748     [ 'BundleName', 'string' ],
       
  1749     [ 'BundleDisplayName', 'string' ],
       
  1750     [ 'MainHTML', 'string' ],
       
  1751     [ 'BundleVersion', 'string' ],
       
  1752  #  [ 'Height', 'int' ],
       
  1753  #  [ 'Width', 'int' ],
       
  1754     [ 'AllowNetworkAccess', 'int' ],
       
  1755     [ 'DriveName', 'string' ],
       
  1756     [ 'BasePath', 'string' ],
       
  1757     [ 'IconPath', 'string' ],
       
  1758     [ 'FileSize', 'int' ],
       
  1759     [ 'Uid', 'int' ],
       
  1760     [ 'NokiaWidget', 'int' ],
       
  1761     [ 'MiniViewEnabled', 'int' ],
       
  1762     [ 'ProcessUid', 'int' ],
       
  1763     [ 'MimeType', 'string'],
       
  1764     [ 'WidgetPackagingFormat', 'string'],
       
  1765     [ 'DBIconPath', 'string'],
       
  1766     [ 'AttributeList', 'string'],
       
  1767     [ 'BlanketPermissionGranted', 'int' ],
       
  1768     [ 'PreInstalled', 'int' ],
       
  1769   );
       
  1770     
       
  1771   print $fh "<entry>\n";
       
  1772   my $encodeddata = {};
       
  1773   foreach my $prop ( @regProperties )
       
  1774     {
       
  1775     my ( $key, $type ) = @$prop;
       
  1776     if($key ne "DBIconPath" && $key ne "WidgetPackagingFormat" && $key ne "AttributeList" && $key ne "BlanketPermissionGranted" && $key ne "PreInstalled")
       
  1777     {
       
  1778         print $fh "<prop>$key<val>$data->{$key}<type>$type</type></val></prop>\n" if defined $data->{$key};
       
  1779     }
       
  1780     
       
  1781     if( $w3c )
       
  1782       {
       
  1783       $encodeddata->{$key} = encodeChar($data->{$key}) if defined $data->{$key};
       
  1784       }
       
  1785     else
       
  1786     {
       
  1787     	if($key eq "BlanketPermissionGranted" || $key eq "PreInstalled")
       
  1788     	{
       
  1789     	 print $fh "<prop>$key<val>$data->{$key}<type>$type</type></val></prop>\n" if defined $data->{$key};
       
  1790     	}
       
  1791     }
       
  1792     }
       
  1793   print $fh "</entry>\n";
       
  1794   print "\n Is a w3c widget? -- $w3c\n";
       
  1795   if( $w3c )
       
  1796     {
       
  1797   my $dbPath = fixFilename(catfile($self->destLocation('C'), CWRT_WEBAPP_REGISTRY));
       
  1798     mkpath dirname($dbPath);
       
  1799     die "ERROR: Can't find CWRTWebAppRegistry.exe in PATH" if !(my $cmd = findCmd('CWRTWebAppRegistry.exe'));
       
  1800     my $regCmd;
       
  1801     
       
  1802     if($encodeddata->{'AttributeList'})
       
  1803     {
       
  1804         print "\n AttributeList argument sent to DB\n";
       
  1805         $regCmd = "$cmd $dbPath $encodeddata->{'BundleIdentifier'} $encodeddata->{'Uid'} $encodeddata->{'BundleDisplayName'} $encodeddata->{'BasePath'} $encodeddata->{'DBIconPath'} $encodeddata->{'WidgetPackagingFormat'} $encodeddata->{'MainHTML'} $encodeddata->{'AttributeList'}";
       
  1806     }
       
  1807     else
       
  1808    {
       
  1809         print "\n AttributeList argument not sent to DB\n";
       
  1810         $regCmd = "$cmd $dbPath $encodeddata->{'BundleIdentifier'} $encodeddata->{'Uid'} $encodeddata->{'BundleDisplayName'} $encodeddata->{'BasePath'} $encodeddata->{'DBIconPath'} $encodeddata->{'WidgetPackagingFormat'} $encodeddata->{'MainHTML'}";
       
  1811     }
       
  1812     print "\n regCmd : $regCmd \n\n";
       
  1813     system($regCmd);
       
  1814     }
       
  1815   }
       
  1816 
       
  1817 #encode the space character
       
  1818 sub encodeChar  
       
  1819   {
       
  1820     my  ($encoded) = @_;
       
  1821 
       
  1822     $encoded =~ s/%/%10/g;
       
  1823     $encoded =~ s/\s/%40/g;
       
  1824     $encoded =~ s/\'/%apos/g;   
       
  1825     $encoded =~ s/&/%amp/g;
       
  1826     $encoded =~ s/</%lt/g;
       
  1827     $encoded =~ s/>/%gt/g;
       
  1828     $encoded =~ s/\"/%quot/g;
       
  1829     return $encoded;
       
  1830   }
       
  1831   
       
  1832   
       
  1833 # Make secssion
       
  1834 sub makeSecSession
       
  1835     {
       
  1836   my ($self, $drive) = @_;
       
  1837   my $secSession;
       
  1838   my $widget_uid;
       
  1839   if($non_nokia_widget)
       
  1840 	{
       
  1841 		$widget_uid = CWRT_WIDGET_UI_NON_NOKIA_UID;
       
  1842 	}
       
  1843 	else
       
  1844 	{
       
  1845   	$widget_uid = CWRT_WIDGET_UI_UID;
       
  1846   }
       
  1847 
       
  1848   if($isSharedLibrary)
       
  1849   {
       
  1850       $secSession = fixFilename(catfile($self->destLocation($drive), 'private', sprintf("%08X", $widget_uid),"data","lib",$sharedFolderName,"secsession"));
       
  1851   }
       
  1852   else
       
  1853   {
       
  1854       $secSession = fixFilename(catfile($self->destLocation($drive), 'private', sprintf("%08X", $widget_uid),"data", $hashval,"secsession"));
       
  1855   }
       
  1856   print "\nGenerating: $secSession\n\n";
       
  1857   
       
  1858   # Write the file
       
  1859   mkpath dirname($secSession);
       
  1860   open OUT, ">$secSession" or die "Failed to open SecSession.xml: $!";
       
  1861 
       
  1862   print OUT "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n<accesspolicy>\n";
       
  1863   if($non_nokia_widget)
       
  1864   {
       
  1865   	print OUT "<domain name=\"Operator\">\n";
       
  1866   }
       
  1867   else
       
  1868   {
       
  1869   	print OUT "<domain name=\"TrustedWidgets\">\n";
       
  1870   }
       
  1871   
       
  1872   if(CWRT_ACCESS_POLICY_PATH) {
       
  1873       my $accesspolicypath = findCmd(CWRT_ACCESS_POLICY_PATH);   
       
  1874         # Copy Secsession capabilities from browser_access_policy.xml if it exists
       
  1875       if (-e $accesspolicypath) {
       
  1876           print "Browser Access Policy File exists :: ",$accesspolicypath,"\n" ;
       
  1877           my $accesspolicy = XMLin($accesspolicypath, keyattr => {domain => 'name'}, forcearray =>['domain'] );
       
  1878             my $domainName;
       
  1879             
       
  1880             if($non_nokia_widget)
       
  1881             {
       
  1882             	$domainName = $accesspolicy->{domain}->{Operator};
       
  1883             }
       
  1884             else
       
  1885             {
       
  1886             	$domainName = $accesspolicy->{domain}->{TrustedWidgets};
       
  1887             }
       
  1888           
       
  1889           my $xml = XMLout($domainName, keeproot => 1);
       
  1890           print OUT $xml;
       
  1891       }
       
  1892       #browser_access_policy.xml does not exist in the path
       
  1893       else {      
       
  1894           print "\n Browser Access policy file '$accesspolicypath' does not exist in the given path\n";
       
  1895           if(!$non_nokia_widget)
       
  1896           {
       
  1897           	print OUT "   <capability name=\"Download\"/>\n   <capability name=\"ApplicationManagement\"/>\n   <capability name=\"WebAppUpdate\"/>\n   <capability name=\"DeviceConfiguration\"/>\n   <capability name=\"NokiaAccount\"/>\n   <capability name=\"ConnectionManagement\"/>\n   <capability name=\"ApplicationManagement.Launch\"/>\n   <capability name=\"SecureStorage\"/>\n   <capability name=\"EventsAndMessaging\"/>\n   <capability name=\"Vibra\"/>\n   <capability name=\"RuntimeInfo\"/>\n   <capability name=\"OviMessagingBus\"/>\n   <capability name=\"NativeUpdate\"/>\n   <capability name=\"LocalConnectivity\"/>\n   <capability name=\"Network\"/>\n   <capability name=\"Cryptographic\"/>\n   <capability name=\"pim.*\"/>\n   <capability name=\"devicestatus.*\"/>\n   <capability name=\"message.*\"/>\n   <capability name=\"sensor.*\"/>\n   <capability name=\"landmark.*\"/>\n   <capability name=\"camera.*\"/>\n   <capability name=\"commlog.*\"/>\n   <capability name=\"media.*\"/>\n   <capability name=\"io.file.*\"/>\n   <capability name=\"player.*\"/>\n   <capability name=\"location.position\"/>\n   <capability name=\"telephony.voicecall\"/>\n   <capability name=\"NokiaAdEnabler\"/>\n";
       
  1898           }
       
  1899         }
       
  1900     }
       
  1901     #Access policy path not defined
       
  1902   else {
       
  1903       print "\n Browser Access policy path not defined \n";
       
  1904       if(!$non_nokia_widget)
       
  1905       {
       
  1906       	print OUT "   <capability name=\"Download\"/>\n   <capability name=\"ApplicationManagement\"/>\n   <capability name=\"WebAppUpdate\"/>\n   <capability name=\"DeviceConfiguration\"/>\n   <capability name=\"NokiaAccount\"/>\n   <capability name=\"ConnectionManagement\"/>\n   <capability name=\"ApplicationManagement.Launch\"/>\n   <capability name=\"SecureStorage\"/>\n   <capability name=\"EventsAndMessaging\"/>\n   <capability name=\"Vibra\"/>\n   <capability name=\"RuntimeInfo\"/>\n   <capability name=\"OviMessagingBus\"/>\n   <capability name=\"NativeUpdate\"/>\n   <capability name=\"LocalConnectivity\"/>\n   <capability name=\"Network\"/>\n   <capability name=\"Cryptographic\"/>\n   <capability name=\"pim.*\"/>\n   <capability name=\"devicestatus.*\"/>\n   <capability name=\"message.*\"/>\n   <capability name=\"sensor.*\"/>\n   <capability name=\"landmark.*\"/>\n   <capability name=\"camera.*\"/>\n   <capability name=\"commlog.*\"/>\n   <capability name=\"media.*\"/>\n   <capability name=\"io.file.*\"/>\n   <capability name=\"player.*\"/>\n   <capability name=\"location.position\"/>\n   <capability name=\"telephony.voicecall\"/>\n   <capability name=\"NokiaAdEnabler\"/>\n";
       
  1907       }
       
  1908   }
       
  1909    
       
  1910     print OUT "</domain>\n";
       
  1911     print OUT "</accesspolicy>\n";
       
  1912     close OUT;
       
  1913 
       
  1914   # Return the generated file
       
  1915   return $secSession;
       
  1916   }
       
  1917 __END__
       
  1918 
       
  1919 =head1 NAME
       
  1920 
       
  1921 installwidgets.pl - A script for generating all the files needed to install Widgets
       
  1922 
       
  1923 =head1 SYNOPSIS
       
  1924 
       
  1925 installwidgets.pl [-h] [-ver] [-v] [-debug] [-e <dir>] [-l <lang_code|lproj.xml>] config.ini
       
  1926 
       
  1927  Options:
       
  1928    -help|h                        Show this help
       
  1929    -version|ver                   Show version number
       
  1930    -verbose|v                     Show verbose output
       
  1931    -debug                         Show debug output
       
  1932    -epocroot|e                    Override value of EPOCROOT
       
  1933    -localization|l                lproj_dir
       
  1934 
       
  1935 A script for generating all the files needed to preinstall Widgets.
       
  1936 
       
  1937  Example:
       
  1938    perl installwidgets.pl -l fr config.ini       Install widgets listed in config.ini using French localization
       
  1939 
       
  1940  Author:
       
  1941    peter.harper@sosco.com
       
  1942 
       
  1943 =head1 DESCRIPTION
       
  1944 
       
  1945 This tool can be used to pre-generate all the files needed to install Widgets. The tool and its dependencies can be placed anywhere on your PATH.
       
  1946 It generates the results in the epoc32 folder - in the appropriate locations for the emulator.
       
  1947 It finds the epoc32 folder using the EPOCROOT environment variable which can be overridden via the -e command line option.
       
  1948 
       
  1949 =head2 CONFIG FILE
       
  1950 
       
  1951 The preferred way to run the tool is via a configuration INI file.
       
  1952 You can list the widgets to install on each drive. You can specify the exact location of the Widget, otherwise it will try and find the Widget via EPOCROOT.
       
  1953 
       
  1954 You can specify whether a widget is intended for the homescreen by adding the text [HomeScreen] after the filename
       
  1955 This will set the BlanketPermissionGranted attribute in the registry.
       
  1956 Widgets intended for the homescreen must have the MiniViewEnabled attribute set in its PLIST file otherwise an error is generated.
       
  1957 
       
  1958     # Widgets to be pre-installed for the ROM
       
  1959     [drive-z]
       
  1960     \somepath\foo.wgz
       
  1961     \somepath\bar.wgz
       
  1962 
       
  1963     # Widgets for the internal disk
       
  1964     [drive-c]
       
  1965     \somepath\widget1.wdgt.zip [HomeScreen]
       
  1966 
       
  1967     # Widgets for the removable disk
       
  1968     [drive-e]
       
  1969     \somepath\widget2.wdgt.zip
       
  1970 
       
  1971     # Commands to run at the end
       
  1972     [run-commands]
       
  1973     dostuff.pl
       
  1974     domorestuff.exe
       
  1975 
       
  1976 =head2 DEPENDENCIES
       
  1977 
       
  1978 The tool has some dependencies which must exist for it to work.
       
  1979 
       
  1980 =over
       
  1981 
       
  1982 =item 1
       
  1983 
       
  1984 png2mbm.pl - A script to generate an MBM file from a PNG
       
  1985 
       
  1986 =item 2
       
  1987 
       
  1988 WidgetRegFiles.exe - an EXE which can generate Symbian REG and LOC files for registering non-native Widget apps.
       
  1989 This tool is built with "SymPort" a native tools port of basic Symbian OS services.
       
  1990 
       
  1991 =item 3
       
  1992 
       
  1993 7z/unzip - For extracting files from the Widget archive.
       
  1994 7Zip will be used in preference to unzip if it's found on your path because it handles Unicode a better.
       
  1995 
       
  1996 =item 4
       
  1997 
       
  1998 GD.pm - Perl support for the GD graphics library for PNG support, see http://www.libgd.org .
       
  1999 
       
  2000 =back
       
  2001 
       
  2002 =head3 INSTALLING GD
       
  2003 
       
  2004 You can install GD automatically with a simple command - however the command you need to use differs depending on the version of Perl you have installed.
       
  2005 At the time of writing Symbian requires Perl version 5.6 - although in my experience Perl 5.8 works okay. To find out which version of Perl you have type "perl -v" on the command line.
       
  2006 
       
  2007 To install the GD library:
       
  2008 
       
  2009 =over
       
  2010 
       
  2011 =item *
       
  2012 
       
  2013 For Perl v5.6: "ppm install http://theoryx5.uwinnipeg.ca/ppmpackages/GD.ppd "
       
  2014 
       
  2015 =item *
       
  2016 
       
  2017 For Perl v5.8: "ppm install http://theoryx5.uwinnipeg.ca/ppms/GD.ppd "
       
  2018 
       
  2019 =back
       
  2020 
       
  2021 =head2 WIDGET INSTALL PROCESS
       
  2022 
       
  2023 Here's a detailed breakdown of what the script does.
       
  2024 
       
  2025 =over
       
  2026 
       
  2027 =item 1
       
  2028 
       
  2029 It gets the lists of Widgets from the config.ini file passed on the command line.
       
  2030 This process is repeated for all Widgets and all drives listed in the config file.
       
  2031 
       
  2032 =item 2
       
  2033 
       
  2034 Any existing Widgets listed in "private\10282f06\WidgetEntryStore.xml" are deleted from the epoc32 tree.
       
  2035 This ensures that there are no problems when testing Widgets in the emulator.
       
  2036 
       
  2037 =item 3
       
  2038 
       
  2039 All the compressed files in the Widget are extracted to a temporary folder.
       
  2040 
       
  2041 =item 4
       
  2042 
       
  2043 The details for the Widget are loaded from its "Info.plist" file.
       
  2044 
       
  2045 =item 5
       
  2046 
       
  2047 A UID is chosen for the widget. This differs depending on whether installation is for an internal drive (z: or c:) or an external drive (e: etc).
       
  2048 
       
  2049 =item 5
       
  2050 
       
  2051 A Symbian MBM file is generated from the "Icon.png" file supplied by the Widgets.
       
  2052 Three different sized icons are generated "88x88", "32x32" and "24x24".
       
  2053 The MBM file is placed in "private/10003a3f/import/apps/NonNative/Resource/[<UID>].mbm".
       
  2054 
       
  2055 =item 6
       
  2056 
       
  2057 "WidgetRegFiles.exe" is executed to generate REG and LOC resource files used to register the Widget as an app in Symbian OS.
       
  2058 These files are placed in "private/10003a3f/import/apps/NonNative/Resource".
       
  2059 
       
  2060 =item 7
       
  2061 
       
  2062 All the widgets files are copied to a folder under "private\10282822".
       
  2063 The Widget's bundle identifier is used to create a unique folder under here for the Widget.
       
  2064 
       
  2065 =item 8
       
  2066 
       
  2067 The Widget registry is generated in "private\10282f06\WidgetEntryStore.xml"
       
  2068 
       
  2069 =item 9
       
  2070 
       
  2071 If Widgets are being preinstalled for ROM an IBY file is created in "epoc32\rom\include\preinstalledwidgets.iby".
       
  2072 A separate IBY file is generated for the localised parts of a Widget "epoc32\rom\include\preinstalledwidgets_rsc.iby".
       
  2073 Separate IBY files (per drive) are generated for Widgets preinstalled to UDA, e.g. preinstalledwidgets_driveC.iby and preinstalledwidgets_driveC_rsc.iby.
       
  2074 These IBY files can be used to add all the Widgets to ROM, ROFS or UDA.
       
  2075 
       
  2076 =back
       
  2077 
       
  2078 =head3 INSTALLING ON HARDWARE USING iMaker
       
  2079 
       
  2080 =over
       
  2081 
       
  2082 =item 1
       
  2083 
       
  2084 Create the following folder structure at the root level.
       
  2085 
       
  2086 X:\variants\content
       
  2087 
       
  2088 =item 2
       
  2089 
       
  2090 Copy the files specified in the generated ibys (preinstalledwidgets_driveC.iby and preinstalledwidgets_driveC_rsc.iby) to X:\variants\content. Preserve the dir structure. (Note, this step will be automated in the future)
       
  2091 
       
  2092 For example if you want the following file on UDA (User Disk Area, C drive on phone) at the following location C:\private\10282f06\WidgetEntryStore.xml
       
  2093 
       
  2094 Drop the file under X:\variants\content\private\10282f06\WidgetEntryStore.xml 
       
  2095 
       
  2096 =item 3
       
  2097 
       
  2098 Run the foll command to generate UDA
       
  2099 
       
  2100 B<Gadget:>
       
  2101 X:\epoc32\tools>imaker -f /epoc32/rom/s60_makefiles/image_conf_sp_rnd_gadget.mk VARIANT_DIR=/variants variantuda
       
  2102 
       
  2103 B<Tube:>
       
  2104 Y:\epoc32\tools>imaker -f /epoc32/rom/config/ncp52/tube/image_conf_tube_ui.mk VARIANT_DIR=/variants variantuda 
       
  2105 
       
  2106 =item 4
       
  2107 
       
  2108 Flash the fpsx file generated under X:\epoc32\rombuild\gadget\uda for Gadget and Y:\epoc32\rombuild\tube\uda for Tube to your device.
       
  2109 
       
  2110 Note: More info on iMaker tool at: L<http://configurationtools.nmp.nokia.com/imaker/wiki/iMakerUserGuide>
       
  2111 
       
  2112 =back
       
  2113 
       
  2114 =head3 LOCALISATION
       
  2115 
       
  2116 Widget handles localization by providing localized resources in various language project directories(lproj_dir), one level deep than the root directory. In order to specify a language variant for pre-installing widget, you need to provide the language project directory name, e.g. 'en' for english, 'fr' for French.
       
  2117 
       
  2118 A list of Nokia supported languages can be found in Widget_lproj.xml or at L<http://wiki.forum.nokia.com/index.php/Web_Runtime_localisation_support>. If the widget does not provide the localized resource for the variant you specified, the default resources in widget's home directory will be used instead. 
       
  2119 
       
  2120 =head3 NOTES
       
  2121 
       
  2122 =over
       
  2123 
       
  2124 =item 1
       
  2125 
       
  2126 The location of the private folder is in the appropriate place for the files to appear in the emulator.
       
  2127 This is different depending on the intended destination drive (see -dd command line option) for the Widget.
       
  2128 e.g. "epoc32/release/winscw/udeb/z/", "epoc32/winscw/c" or "epoc32/winscw/e"
       
  2129 
       
  2130 =item 2
       
  2131 
       
  2132 Files are extracted to epoc32 on the current drive relative to the EPOCROOT environment variable or the value given for -epocroot (-e) on the command line.
       
  2133 
       
  2134 =item 3
       
  2135 
       
  2136 A different IBY file is generated for each drive.
       
  2137 
       
  2138 =over
       
  2139 
       
  2140 =item *
       
  2141 
       
  2142 Z: - \epoc32\rom\include\preinstalledwidgets.iby
       
  2143 
       
  2144 =item *
       
  2145 
       
  2146 C: - \epoc32\rom\include\preinstalledwidgets_driveC.iby
       
  2147 
       
  2148 =item *
       
  2149 
       
  2150 E: - \epoc32\rom\include\preinstalledwidgets_driveE.iby
       
  2151 
       
  2152 =back
       
  2153 
       
  2154 There are separate resource files for localised resources e.g. preinstalledwidgets_rsc.iby.
       
  2155 
       
  2156 =cut