Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
VirtualFileSystem.Android.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 #if SILICONSTUDIO_PLATFORM_ANDROID
4 using System;
5 using System.IO;
6 using System.Linq;
7 using System.Threading.Tasks;
8 using System.IO.Compression.Zip;
9 using Android.Content.PM;
10 using SiliconStudio.Core.Diagnostics;
11 using SiliconStudio.Core.Serialization;
12 
13 namespace SiliconStudio.Core.IO
14 {
15  public static partial class VirtualFileSystem
16  {
17  private const string LastExtractedApkFileName = "LastExtractedAPK";
18 
19  public static async Task UnpackAPK()
20  {
21  // get the apk last update time
22  var packageManager = PlatformAndroid.Context.PackageManager;
23  var packageInfo = packageManager.GetPackageInfo(PlatformAndroid.Context.PackageName, PackageInfoFlags.Activities);
24  var lastUpdateTime = packageInfo.LastUpdateTime;
25  var sourceDir = PlatformAndroid.Context.ApplicationInfo.SourceDir;
26 
27  // evaluate if asset data should be extracted from apk file
28  var shouldExtractAssets = true;
29  if (ApplicationTemporary.FileExists(LastExtractedApkFileName))
30  {
31  Int64 extractedLastUpdateTime = 0;
32  using (var file = ApplicationTemporary.OpenStream(LastExtractedApkFileName, VirtualFileMode.Open, VirtualFileAccess.Read))
33  {
34  var binaryReader = new BinarySerializationReader(file);
35  binaryReader.Serialize(ref extractedLastUpdateTime, ArchiveMode.Deserialize);
36  }
37 
38  shouldExtractAssets = extractedLastUpdateTime != lastUpdateTime;
39  }
40 
41  // Copy assets
42  if (shouldExtractAssets)
43  {
44  var assets = PlatformAndroid.Context.Assets;
45 
46  // Make sure assets exists
47  var logger = GlobalLogger.GetLogger("VFS");
48  CopyFileOrDirectory(logger, sourceDir, "assets/data/", string.Empty);
49 
50  // update value of extracted last update time
51  using (var stream = ApplicationTemporary.OpenStream(LastExtractedApkFileName, VirtualFileMode.Create, VirtualFileAccess.Write, VirtualFileShare.None))
52  {
53  var binaryWriter = new BinarySerializationWriter(stream);
54  binaryWriter.Write(lastUpdateTime);
55  }
56  }
57  }
58 
59  private static void CopyFileOrDirectory(Logger logger, string sourceDir, string root, string path)
60  {
61  // Root path not handled
62  if (root.Length == 0)
63  throw new NotSupportedException();
64 
65  try
66  {
67  var zipFile = new ZipFile(sourceDir);
68  foreach (var zipEntry in zipFile.GetAllEntries())
69  {
70  var zipFilename = zipEntry.FilenameInZip;
71  if (!zipFilename.StartsWith(root))
72  continue;
73 
74  // Get filename without leading "assets/data"
75  var assetFilename = zipFilename.Substring(root.Length);
76 
77  var fullPath = path + assetFilename;
78  var directoryName = VirtualFileSystem.GetParentFolder(fullPath);
79 
80  try
81  {
82  if (directoryName != string.Empty)
83  ApplicationData.CreateDirectory(directoryName);
84  }
85  catch (IOException)
86  {
87  }
88 
89  using (var output = ApplicationData.OpenStream(fullPath, VirtualFileMode.Create, VirtualFileAccess.Write))
90  zipFile.ExtractFile(zipEntry, output);
91  }
92  }
93  catch (IOException ex)
94  {
95  logger.Info("I/O Exception", ex);
96  }
97  }
98  }
99 }
100 #endif