Compare commits
	
		
			5 Commits
		
	
	
		
			master
			...
			LiisaChang
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 3eea75f7db | |||
| f145eff6a1 | |||
| ec375254b7 | |||
| 00e80e27ca | |||
| 84f4348b91 | 
| @ -1,14 +0,0 @@ | |||||||
| # This file is automatically generated by Android Tools. |  | ||||||
| # Do not modify this file -- YOUR CHANGES WILL BE ERASED! |  | ||||||
| # |  | ||||||
| # This file must be checked in Version Control Systems. |  | ||||||
| # |  | ||||||
| # To customize properties used by the Ant build system edit |  | ||||||
| # "ant.properties", and override values to adapt the script to your |  | ||||||
| # project structure. |  | ||||||
| # |  | ||||||
| # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): |  | ||||||
| proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt |  | ||||||
| 
 |  | ||||||
| # Project target. |  | ||||||
| target=android-19 |  | ||||||
| Before Width: | Height: | Size: 2.1 KiB | 
| Before Width: | Height: | Size: 1.1 KiB | 
| Before Width: | Height: | Size: 1.4 KiB | 
| Before Width: | Height: | Size: 1.0 MiB | 
| Before Width: | Height: | Size: 1.0 MiB | 
| Before Width: | Height: | Size: 2.9 KiB | 
| Before Width: | Height: | Size: 22 KiB | 
| Before Width: | Height: | Size: 22 KiB | 
| Before Width: | Height: | Size: 1.4 KiB | 
| Before Width: | Height: | Size: 5.1 KiB | 
| Before Width: | Height: | Size: 5.2 KiB | 
| @ -1,4 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="utf-8"?> |  | ||||||
| <resources> |  | ||||||
| 	<string name="app_id"></string> |  | ||||||
| </resources> |  | ||||||
| @ -1,44 +0,0 @@ | |||||||
| /* |  | ||||||
|  * Copyright (C) 2012 The Android Open Source Project |  | ||||||
|  * |  | ||||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
|  * you may not use this file except in compliance with the License. |  | ||||||
|  * You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, software |  | ||||||
|  * distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
|  * See the License for the specific language governing permissions and |  | ||||||
|  * limitations under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package com.epicgames.Gallery; |  | ||||||
| 
 |  | ||||||
| import com.google.android.vending.expansion.downloader.DownloaderClientMarshaller; |  | ||||||
| 
 |  | ||||||
| import android.content.BroadcastReceiver; |  | ||||||
| import android.content.Context; |  | ||||||
| import android.content.Intent; |  | ||||||
| import android.content.pm.PackageManager.NameNotFoundException; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * You should start your derived downloader class when this receiver gets the message  |  | ||||||
|  * from the alarm service using the provided service helper function within the |  | ||||||
|  * DownloaderClientMarshaller. This class must be then registered in your AndroidManifest.xml |  | ||||||
|  * file with a section like this: |  | ||||||
|  *         <receiver android:name=".AlarmReceiver"/> |  | ||||||
|  */ |  | ||||||
| public class AlarmReceiver extends BroadcastReceiver { |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void onReceive(Context context, Intent intent) { |  | ||||||
|         try { |  | ||||||
|             DownloaderClientMarshaller.startDownloadServiceIfRequired(context, intent, OBBDownloaderService.class); |  | ||||||
|         } catch (NameNotFoundException e) { |  | ||||||
|             e.printStackTrace(); |  | ||||||
|         }        |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| @ -1,809 +0,0 @@ | |||||||
| /* |  | ||||||
|  * Copyright (C) 2012 The Android Open Source Project |  | ||||||
|  * |  | ||||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
|  * you may not use this file except in compliance with the License. |  | ||||||
|  * You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, software |  | ||||||
|  * distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
|  * See the License for the specific language governing permissions and |  | ||||||
|  * limitations under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package com.epicgames.Gallery; |  | ||||||
| 
 |  | ||||||
| import com.android.vending.expansion.zipfile.ZipResourceFile; |  | ||||||
| import com.android.vending.expansion.zipfile.ZipResourceFile.ZipEntryRO; |  | ||||||
| import com.google.android.vending.expansion.downloader.Constants; |  | ||||||
| import com.google.android.vending.expansion.downloader.DownloadProgressInfo; |  | ||||||
| import com.google.android.vending.expansion.downloader.DownloaderClientMarshaller; |  | ||||||
| import com.google.android.vending.expansion.downloader.DownloaderServiceMarshaller; |  | ||||||
| import com.google.android.vending.expansion.downloader.Helpers; |  | ||||||
| import com.google.android.vending.expansion.downloader.IDownloaderClient; |  | ||||||
| import com.google.android.vending.expansion.downloader.IDownloaderService; |  | ||||||
| import com.google.android.vending.expansion.downloader.IStub; |  | ||||||
| 
 |  | ||||||
| import android.app.Activity; |  | ||||||
| import android.app.PendingIntent; |  | ||||||
| import android.app.AlertDialog; |  | ||||||
| import android.app.AlertDialog.Builder; |  | ||||||
| import android.content.Intent; |  | ||||||
| import android.content.pm.PackageManager.NameNotFoundException; |  | ||||||
| import android.content.DialogInterface; |  | ||||||
| import android.content.DialogInterface.OnClickListener; |  | ||||||
| import android.os.AsyncTask; |  | ||||||
| import android.os.Bundle; |  | ||||||
| import android.os.Messenger; |  | ||||||
| import android.os.SystemClock; |  | ||||||
| import android.provider.Settings; |  | ||||||
| import android.util.Log; |  | ||||||
| import android.view.View; |  | ||||||
| import android.widget.Button; |  | ||||||
| import android.widget.ProgressBar; |  | ||||||
| import android.widget.TextView; |  | ||||||
| 
 |  | ||||||
| import java.io.DataInputStream; |  | ||||||
| import java.io.IOException; |  | ||||||
| import java.io.File; |  | ||||||
| import java.io.FileReader; |  | ||||||
| import java.io.FileWriter; |  | ||||||
| import java.io.BufferedReader; |  | ||||||
| import java.io.BufferedWriter; |  | ||||||
| import java.util.zip.CRC32; |  | ||||||
| import java.util.Map; |  | ||||||
| import java.util.HashMap; |  | ||||||
| import java.util.List; |  | ||||||
| import java.util.ArrayList; |  | ||||||
| 
 |  | ||||||
| import com.epicgames.ue4.GameActivity; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * This is sample code for a project built against the downloader library. It |  | ||||||
|  * implements the IDownloaderClient that the client marshaler will talk to as |  | ||||||
|  * messages are delivered from the DownloaderService. |  | ||||||
|  */ |  | ||||||
| public class DownloaderActivity extends Activity implements IDownloaderClient { |  | ||||||
|     private static final String LOG_TAG = "LVLDownloader"; |  | ||||||
|     private ProgressBar mPB; |  | ||||||
| 
 |  | ||||||
|     private TextView mStatusText; |  | ||||||
|     private TextView mProgressFraction; |  | ||||||
|     private TextView mProgressPercent; |  | ||||||
|     private TextView mAverageSpeed; |  | ||||||
|     private TextView mTimeRemaining; |  | ||||||
| 
 |  | ||||||
|     private View mDashboard; |  | ||||||
|     private View mCellMessage; |  | ||||||
| 
 |  | ||||||
|     private Button mPauseButton; |  | ||||||
|     private Button mWiFiSettingsButton; |  | ||||||
| 
 |  | ||||||
|     private boolean mStatePaused; |  | ||||||
|     private int mState; |  | ||||||
| 
 |  | ||||||
|     private IDownloaderService mRemoteService; |  | ||||||
| 
 |  | ||||||
|     private IStub mDownloaderClientStub; |  | ||||||
| 	 |  | ||||||
| 	private final CharSequence[] OBBSelectItems = { "Use Store Data", "Use Development Data" }; |  | ||||||
| 
 |  | ||||||
| 	 |  | ||||||
|     private void setState(int newState) { |  | ||||||
|         if (mState != newState) { |  | ||||||
|             mState = newState; |  | ||||||
|             mStatusText.setText(Helpers.getDownloaderStringResourceIDFromState(newState)); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private void setButtonPausedState(boolean paused) { |  | ||||||
|         mStatePaused = paused; |  | ||||||
|         int stringResourceID = paused ? R.string.text_button_resume : |  | ||||||
|                 R.string.text_button_pause; |  | ||||||
|         mPauseButton.setText(stringResourceID); |  | ||||||
|     } |  | ||||||
| 	 |  | ||||||
| 	static DownloaderActivity _download; |  | ||||||
| 	 |  | ||||||
| 	private Intent OutputData; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Go through each of the APK Expansion files defined in the structure above |  | ||||||
|      * and determine if the files are present and match the required size. Free |  | ||||||
|      * applications should definitely consider doing this, as this allows the |  | ||||||
|      * application to be launched for the first time without having a network |  | ||||||
|      * connection present. Paid applications that use LVL should probably do at |  | ||||||
|      * least one LVL check that requires the network to be present, so this is |  | ||||||
|      * not as necessary. |  | ||||||
|      *  |  | ||||||
|      * @return true if they are present. |  | ||||||
|      */ |  | ||||||
|     boolean expansionFilesDelivered() { |  | ||||||
| 		 |  | ||||||
|         for (OBBData.XAPKFile xf : OBBData.xAPKS) { |  | ||||||
|             String fileName = Helpers.getExpansionAPKFileName(this, xf.mIsMain, xf.mFileVersion, OBBData.AppType); |  | ||||||
| 			GameActivity.Log.debug("Checking for file : " + fileName); |  | ||||||
| 			String fileForNewFile = Helpers.generateSaveFileName(this, fileName); |  | ||||||
| 			String fileForDevFile = Helpers.generateSaveFileNameDevelopment(this, fileName); |  | ||||||
| 			GameActivity.Log.debug("which is really being resolved to : " + fileForNewFile + "\n Or : " + fileForDevFile); |  | ||||||
|             if (!Helpers.doesFileExist(this, fileName, xf.mFileSize, false) && |  | ||||||
| 				!Helpers.doesFileExistDev(this, fileName, xf.mFileSize, false)) |  | ||||||
|                 return false; |  | ||||||
|         } |  | ||||||
|         return true; |  | ||||||
|     } |  | ||||||
| 	 |  | ||||||
| 	boolean onlySingleExpansionFileFound() { |  | ||||||
| 		for (OBBData.XAPKFile xf : OBBData.xAPKS) { |  | ||||||
|             String fileName = Helpers.getExpansionAPKFileName(this, xf.mIsMain, xf.mFileVersion, OBBData.AppType); |  | ||||||
| 			GameActivity.Log.debug("Checking for file : " + fileName); |  | ||||||
| 			String fileForNewFile = Helpers.generateSaveFileName(this, fileName); |  | ||||||
| 			String fileForDevFile = Helpers.generateSaveFileNameDevelopment(this, fileName); |  | ||||||
| 			 |  | ||||||
| 			if (Helpers.doesFileExist(this, fileName, xf.mFileSize, false) && |  | ||||||
| 				Helpers.doesFileExistDev(this, fileName, xf.mFileSize, false)) |  | ||||||
|                 return false; |  | ||||||
| 		} |  | ||||||
| 		 |  | ||||||
| 		return true;		 |  | ||||||
| 	} |  | ||||||
| 	 |  | ||||||
| 	File getFileDetailsCacheFile() { |  | ||||||
| 		return new File(this.getExternalFilesDir(null), "cacheFile.txt"); |  | ||||||
| 	} |  | ||||||
| 	 |  | ||||||
| 	boolean expansionFilesUptoData() { |  | ||||||
| 	 |  | ||||||
| 		File cacheFile = getFileDetailsCacheFile(); |  | ||||||
| 		// Read data into an array or something... |  | ||||||
| 		Map<String, Long> fileDetailsMap = new HashMap<String, Long>(); |  | ||||||
| 		 |  | ||||||
| 		if(cacheFile.exists()) { |  | ||||||
| 			try { |  | ||||||
| 				FileReader fileCache = new FileReader(cacheFile); |  | ||||||
| 				BufferedReader bufferedFileCache = new BufferedReader(fileCache); |  | ||||||
| 				List<String> lines = new ArrayList<String>(); |  | ||||||
| 				String line = null; |  | ||||||
| 				while ((line = bufferedFileCache.readLine()) != null) { |  | ||||||
| 					lines.add(line); |  | ||||||
| 				} |  | ||||||
| 				bufferedFileCache.close(); |  | ||||||
| 				 |  | ||||||
| 				for(String dataLine : lines) |  | ||||||
| 				{ |  | ||||||
| 					GameActivity.Log.debug("Splitting dataLine => " + dataLine); |  | ||||||
| 					String[] parts = dataLine.split(","); |  | ||||||
| 					fileDetailsMap.put(parts[0], Long.parseLong(parts[1])); |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 			catch(Exception e) |  | ||||||
| 			{ |  | ||||||
| 				GameActivity.Log.debug("Exception thrown during file details reading."); |  | ||||||
| 				e.printStackTrace(); |  | ||||||
| 				fileDetailsMap.clear(); |  | ||||||
| 			}	 |  | ||||||
| 		} |  | ||||||
| 		 |  | ||||||
| 		for (OBBData.XAPKFile xf : OBBData.xAPKS) { |  | ||||||
|             String fileName = Helpers.getExpansionAPKFileName(this, xf.mIsMain, xf.mFileVersion, OBBData.AppType); |  | ||||||
| 			String fileForNewFile = Helpers.generateSaveFileName(this, fileName); |  | ||||||
| 			String fileForDevFile = Helpers.generateSaveFileNameDevelopment(this, fileName); |  | ||||||
| 			// check to see if time/data on files match cached version |  | ||||||
| 			// if not return false |  | ||||||
| 			File srcFile = new File(fileForNewFile); |  | ||||||
| 			File srcDevFile = new File(fileForDevFile); |  | ||||||
| 			long lastModified = srcFile.lastModified(); |  | ||||||
| 			long lastModifiedDev = srcDevFile.lastModified(); |  | ||||||
| 			if(!(srcFile.exists() && fileDetailsMap.containsKey(fileName) && lastModified == fileDetailsMap.get(fileName))  |  | ||||||
| 				&& |  | ||||||
| 			   !(srcDevFile.exists() && fileDetailsMap.containsKey(fileName) && lastModifiedDev == fileDetailsMap.get(fileName))) |  | ||||||
| 				return false; |  | ||||||
| 		} |  | ||||||
| 		return true; |  | ||||||
| 	} |  | ||||||
| 	 |  | ||||||
| 	static private void RemoveOBBFile(int OBBToDelete) { |  | ||||||
| 		 |  | ||||||
| 		for (OBBData.XAPKFile xf : OBBData.xAPKS) { |  | ||||||
| 		    String fileName = Helpers.getExpansionAPKFileName(DownloaderActivity._download, xf.mIsMain, xf.mFileVersion, OBBData.AppType); |  | ||||||
| 			switch(OBBToDelete) |  | ||||||
| 			{ |  | ||||||
| 			case 0: |  | ||||||
| 				String fileForNewFile = Helpers.generateSaveFileName(DownloaderActivity._download, fileName); |  | ||||||
| 				File srcFile = new File(fileForNewFile); |  | ||||||
| 				srcFile.delete(); |  | ||||||
| 				break; |  | ||||||
| 			case 1: |  | ||||||
| 				String fileForDevFile = Helpers.generateSaveFileNameDevelopment(DownloaderActivity._download, fileName); |  | ||||||
| 				File srcDevFile = new File(fileForDevFile); |  | ||||||
| 				srcDevFile.delete(); |  | ||||||
| 				break; |  | ||||||
| 			} |  | ||||||
| 		}		 |  | ||||||
| 	} |  | ||||||
| 	 |  | ||||||
| 	private void ProcessOBBFiles() |  | ||||||
| 	{ |  | ||||||
| 		if(GameActivity.Get().VerifyOBBOnStartUp && !expansionFilesUptoData()) { |  | ||||||
| 				validateXAPKZipFiles(); |  | ||||||
| 		} else { |  | ||||||
| 				OutputData.putExtra(GameActivity.DOWNLOAD_RETURN_NAME, GameActivity.DOWNLOAD_FILES_PRESENT);		 |  | ||||||
| 				setResult(RESULT_OK, OutputData); |  | ||||||
| 				finish(); |  | ||||||
| 				overridePendingTransition(R.anim.noaction, R.anim.noaction); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Calculating a moving average for the validation speed so we don't get |  | ||||||
|      * jumpy calculations for time etc. |  | ||||||
|      */ |  | ||||||
|     static private final float SMOOTHING_FACTOR = 0.005f; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Used by the async task |  | ||||||
|      */ |  | ||||||
|     private boolean mCancelValidation; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Go through each of the Expansion APK files and open each as a zip file. |  | ||||||
|      * Calculate the CRC for each file and return false if any fail to match. |  | ||||||
|      *  |  | ||||||
|      * @return true if XAPKZipFile is successful |  | ||||||
|      */ |  | ||||||
|     void validateXAPKZipFiles() { |  | ||||||
|         AsyncTask<Object, DownloadProgressInfo, Boolean> validationTask = new AsyncTask<Object, DownloadProgressInfo, Boolean>() { |  | ||||||
| 
 |  | ||||||
|             @Override |  | ||||||
|             protected void onPreExecute() { |  | ||||||
|                 mDashboard.setVisibility(View.VISIBLE); |  | ||||||
|                 mCellMessage.setVisibility(View.GONE); |  | ||||||
|                 mStatusText.setText(R.string.text_verifying_download); |  | ||||||
|                 mPauseButton.setOnClickListener(new View.OnClickListener() { |  | ||||||
|                     @Override |  | ||||||
|                     public void onClick(View view) { |  | ||||||
|                         mCancelValidation = true; |  | ||||||
|                     } |  | ||||||
|                 }); |  | ||||||
| 				mPauseButton.setVisibility(View.GONE); |  | ||||||
|                 // mPauseButton.setText(R.string.text_button_cancel_verify); |  | ||||||
|                 super.onPreExecute(); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             @Override |  | ||||||
|             protected Boolean doInBackground(Object... params) { |  | ||||||
|                 for (OBBData.XAPKFile xf : OBBData.xAPKS) { |  | ||||||
|                     String fileName = Helpers.getExpansionAPKFileName( |  | ||||||
|                             DownloaderActivity.this, |  | ||||||
|                             xf.mIsMain, xf.mFileVersion, OBBData.AppType); |  | ||||||
| 					boolean normalFile = Helpers.doesFileExist(DownloaderActivity.this, fileName, xf.mFileSize, false); |  | ||||||
| 					boolean devFile = Helpers.doesFileExistDev(DownloaderActivity.this, fileName, xf.mFileSize, false); |  | ||||||
| 							 |  | ||||||
|                     if (!normalFile &&	!devFile ) |  | ||||||
|                         return false; |  | ||||||
| 					 |  | ||||||
| 					if(normalFile) |  | ||||||
|                     { |  | ||||||
| 						fileName = Helpers.generateSaveFileName(DownloaderActivity.this, fileName); |  | ||||||
| 					} |  | ||||||
| 					else |  | ||||||
| 					{ |  | ||||||
| 						fileName = Helpers.generateSaveFileNameDevelopment(DownloaderActivity.this, fileName); |  | ||||||
| 					}			 |  | ||||||
| 					 |  | ||||||
|                     ZipResourceFile zrf; |  | ||||||
|                     byte[] buf = new byte[1024 * 256]; |  | ||||||
|                     try { |  | ||||||
|                         zrf = new ZipResourceFile(fileName); |  | ||||||
|                         ZipEntryRO[] entries = zrf.getAllEntries(); |  | ||||||
|                         /** |  | ||||||
|                          * First calculate the total compressed length |  | ||||||
|                          */ |  | ||||||
|                         long totalCompressedLength = 0; |  | ||||||
|                         for (ZipEntryRO entry : entries) { |  | ||||||
|                             totalCompressedLength += entry.mCompressedLength; |  | ||||||
|                         } |  | ||||||
|                         float averageVerifySpeed = 0; |  | ||||||
|                         long totalBytesRemaining = totalCompressedLength; |  | ||||||
|                         long timeRemaining; |  | ||||||
|                         /** |  | ||||||
|                          * Then calculate a CRC for every file in the Zip file, |  | ||||||
|                          * comparing it to what is stored in the Zip directory. |  | ||||||
|                          * Note that for compressed Zip files we must extract |  | ||||||
|                          * the contents to do this comparison. |  | ||||||
|                          */ |  | ||||||
|                         for (ZipEntryRO entry : entries) { |  | ||||||
|                             if (-1 != entry.mCRC32) { |  | ||||||
|                                 long length = entry.mUncompressedLength; |  | ||||||
|                                 CRC32 crc = new CRC32(); |  | ||||||
|                                 DataInputStream dis = null; |  | ||||||
|                                 try { |  | ||||||
|                                     dis = new DataInputStream( |  | ||||||
|                                             zrf.getInputStream(entry.mFileName)); |  | ||||||
| 
 |  | ||||||
|                                     long startTime = SystemClock.uptimeMillis(); |  | ||||||
|                                     while (length > 0) { |  | ||||||
|                                         int seek = (int) (length > buf.length ? buf.length |  | ||||||
|                                                 : length); |  | ||||||
|                                         dis.readFully(buf, 0, seek); |  | ||||||
|                                         crc.update(buf, 0, seek); |  | ||||||
|                                         length -= seek; |  | ||||||
|                                         long currentTime = SystemClock.uptimeMillis(); |  | ||||||
|                                         long timePassed = currentTime - startTime; |  | ||||||
|                                         if (timePassed > 0) { |  | ||||||
|                                             float currentSpeedSample = (float) seek |  | ||||||
|                                                     / (float) timePassed; |  | ||||||
|                                             if (0 != averageVerifySpeed) { |  | ||||||
|                                                 averageVerifySpeed = SMOOTHING_FACTOR |  | ||||||
|                                                         * currentSpeedSample |  | ||||||
|                                                         + (1 - SMOOTHING_FACTOR) |  | ||||||
|                                                         * averageVerifySpeed; |  | ||||||
|                                             } else { |  | ||||||
|                                                 averageVerifySpeed = currentSpeedSample; |  | ||||||
|                                             } |  | ||||||
|                                             totalBytesRemaining -= seek; |  | ||||||
|                                             timeRemaining = (long) (totalBytesRemaining / averageVerifySpeed); |  | ||||||
|                                             this.publishProgress( |  | ||||||
|                                                     new DownloadProgressInfo( |  | ||||||
|                                                             totalCompressedLength, |  | ||||||
|                                                             totalCompressedLength |  | ||||||
|                                                                     - totalBytesRemaining, |  | ||||||
|                                                             timeRemaining, |  | ||||||
|                                                             averageVerifySpeed) |  | ||||||
|                                                     ); |  | ||||||
|                                         } |  | ||||||
|                                         startTime = currentTime; |  | ||||||
|                                         if (mCancelValidation) |  | ||||||
|                                             return true; |  | ||||||
|                                     } |  | ||||||
|                                     if (crc.getValue() != entry.mCRC32) { |  | ||||||
|                                         Log.e(Constants.TAG, |  | ||||||
|                                                 "CRC does not match for entry: " |  | ||||||
|                                                         + entry.mFileName); |  | ||||||
|                                         Log.e(Constants.TAG, |  | ||||||
|                                                 "In file: " + entry.getZipFileName()); |  | ||||||
|                                         return false; |  | ||||||
|                                     } |  | ||||||
|                                 } finally { |  | ||||||
|                                     if (null != dis) { |  | ||||||
|                                         dis.close(); |  | ||||||
|                                     } |  | ||||||
|                                 } |  | ||||||
|                             } |  | ||||||
|                         } |  | ||||||
|                     } catch (IOException e) { |  | ||||||
|                         e.printStackTrace(); |  | ||||||
|                         return false; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|                 return true; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             @Override |  | ||||||
|             protected void onProgressUpdate(DownloadProgressInfo... values) { |  | ||||||
|                 onDownloadProgress(values[0]); |  | ||||||
|                 super.onProgressUpdate(values); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             @Override |  | ||||||
|             protected void onPostExecute(Boolean result) { |  | ||||||
|                 if (result) { |  | ||||||
| 					// save details to cache file... |  | ||||||
| 					try { |  | ||||||
| 						File cacheFile = getFileDetailsCacheFile(); |  | ||||||
| 						FileWriter fileCache = new FileWriter(cacheFile); |  | ||||||
| 						BufferedWriter bufferedFileCache = new BufferedWriter(fileCache); |  | ||||||
| 					 |  | ||||||
| 										 |  | ||||||
| 						for (OBBData.XAPKFile xf : OBBData.xAPKS) { |  | ||||||
| 							String fileName = Helpers.getExpansionAPKFileName(DownloaderActivity.this, xf.mIsMain, xf.mFileVersion, OBBData.AppType); |  | ||||||
| 							String fileForNewFile = Helpers.generateSaveFileName(DownloaderActivity.this, fileName); |  | ||||||
| 							String fileForDevFile = Helpers.generateSaveFileNameDevelopment(DownloaderActivity.this, fileName); |  | ||||||
| 														 |  | ||||||
| 							GameActivity.Log.debug("Writing details for file : " + fileName); |  | ||||||
| 								 |  | ||||||
| 							File srcFile = new File(fileForNewFile); |  | ||||||
| 							File srcDevFile = new File(fileForDevFile); |  | ||||||
| 							if(srcFile.exists()) { |  | ||||||
| 								long lastModified = srcFile.lastModified(); |  | ||||||
| 								bufferedFileCache.write(fileName); |  | ||||||
| 								bufferedFileCache.write(","); |  | ||||||
| 								bufferedFileCache.write(new Long(lastModified).toString()); |  | ||||||
| 								bufferedFileCache.newLine(); |  | ||||||
| 								GameActivity.Log.debug("Details for file : " + fileName + " with modified time of " + new Long(lastModified).toString() ); |  | ||||||
| 							}	 |  | ||||||
| 							else { |  | ||||||
| 								long lastModified = srcDevFile.lastModified(); |  | ||||||
| 								bufferedFileCache.write(fileName); |  | ||||||
| 								bufferedFileCache.write(","); |  | ||||||
| 								bufferedFileCache.write(new Long(lastModified).toString()); |  | ||||||
| 								bufferedFileCache.newLine(); |  | ||||||
| 								GameActivity.Log.debug("Details for file : " + fileName + " with modified time of " + new Long(lastModified).toString() ); |  | ||||||
| 							}							 |  | ||||||
| 						} |  | ||||||
| 						 |  | ||||||
| 						bufferedFileCache.close(); |  | ||||||
| 						 |  | ||||||
| 					} |  | ||||||
| 					catch(Exception e) |  | ||||||
| 					{ |  | ||||||
| 						GameActivity.Log.debug("Exception thrown during file details writing."); |  | ||||||
| 						e.printStackTrace(); |  | ||||||
| 					} |  | ||||||
| 					/* |  | ||||||
|                     mDashboard.setVisibility(View.VISIBLE); |  | ||||||
|                     mCellMessage.setVisibility(View.GONE); |  | ||||||
|                     mStatusText.setText(R.string.text_validation_complete); |  | ||||||
|                     mPauseButton.setOnClickListener(new View.OnClickListener() { |  | ||||||
|                         @Override |  | ||||||
|                         public void onClick(View view) { |  | ||||||
| 							OutputData.putExtra(GameActivity.DOWNLOAD_RETURN_NAME, GameActivity.DOWNLOAD_FILES_PRESENT);		 |  | ||||||
| 							setResult(RESULT_OK, OutputData); |  | ||||||
| 							finish(); |  | ||||||
|                         } |  | ||||||
|                     }); |  | ||||||
|                     mPauseButton.setText(android.R.string.ok); |  | ||||||
| 					*/ |  | ||||||
| 					OutputData.putExtra(GameActivity.DOWNLOAD_RETURN_NAME, GameActivity.DOWNLOAD_FILES_PRESENT);		 |  | ||||||
| 					setResult(RESULT_OK, OutputData); |  | ||||||
| 					finish(); |  | ||||||
| 					 |  | ||||||
| 					 |  | ||||||
|                 } else { |  | ||||||
| 					// clear cache file if it exists... |  | ||||||
| 					File cacheFile = getFileDetailsCacheFile(); |  | ||||||
| 					if(cacheFile.exists()) { |  | ||||||
| 						cacheFile.delete(); |  | ||||||
| 					} |  | ||||||
| 					 |  | ||||||
|                     mDashboard.setVisibility(View.VISIBLE); |  | ||||||
|                     mCellMessage.setVisibility(View.GONE); |  | ||||||
|                     mStatusText.setText(R.string.text_validation_failed); |  | ||||||
|                     mPauseButton.setOnClickListener(new View.OnClickListener() { |  | ||||||
|                         @Override |  | ||||||
|                         public void onClick(View view) { |  | ||||||
| 							OutputData.putExtra(GameActivity.DOWNLOAD_RETURN_NAME, GameActivity.DOWNLOAD_INVALID);		 |  | ||||||
| 							setResult(RESULT_OK, OutputData); |  | ||||||
| 							finish(); |  | ||||||
|                         } |  | ||||||
|                     }); |  | ||||||
|                     mPauseButton.setText(android.R.string.cancel); |  | ||||||
|                 } |  | ||||||
|                 super.onPostExecute(result); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|         }; |  | ||||||
|         validationTask.execute(new Object()); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * If the download isn't present, we initialize the download UI. This ties |  | ||||||
|      * all of the controls into the remote service calls. |  | ||||||
|      */ |  | ||||||
|     private void initializeDownloadUI() { |  | ||||||
|         mDownloaderClientStub = DownloaderClientMarshaller.CreateStub |  | ||||||
|                 (this, OBBDownloaderService.class); |  | ||||||
|         setContentView(R.layout.downloader_progress); |  | ||||||
| 
 |  | ||||||
|         mPB = (ProgressBar) findViewById(R.id.progressBar); |  | ||||||
|         mStatusText = (TextView) findViewById(R.id.statusText); |  | ||||||
|         mProgressFraction = (TextView) findViewById(R.id.progressAsFraction); |  | ||||||
|         mProgressPercent = (TextView) findViewById(R.id.progressAsPercentage); |  | ||||||
|         mAverageSpeed = (TextView) findViewById(R.id.progressAverageSpeed); |  | ||||||
|         mTimeRemaining = (TextView) findViewById(R.id.progressTimeRemaining); |  | ||||||
|         mDashboard = findViewById(R.id.downloaderDashboard); |  | ||||||
|         mCellMessage = findViewById(R.id.approveCellular); |  | ||||||
|         mPauseButton = (Button) findViewById(R.id.pauseButton); |  | ||||||
|         mWiFiSettingsButton = (Button) findViewById(R.id.wifiSettingsButton); |  | ||||||
| 
 |  | ||||||
|         mPauseButton.setOnClickListener(new View.OnClickListener() { |  | ||||||
|             @Override |  | ||||||
|             public void onClick(View view) { |  | ||||||
|                 if (mStatePaused) { |  | ||||||
|                     mRemoteService.requestContinueDownload(); |  | ||||||
|                 } else { |  | ||||||
|                     mRemoteService.requestPauseDownload(); |  | ||||||
|                 } |  | ||||||
|                 setButtonPausedState(!mStatePaused); |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|         mWiFiSettingsButton.setOnClickListener(new View.OnClickListener() { |  | ||||||
| 
 |  | ||||||
|             @Override |  | ||||||
|             public void onClick(View v) { |  | ||||||
|                 startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS)); |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|         Button resumeOnCell = (Button) findViewById(R.id.resumeOverCellular); |  | ||||||
|         resumeOnCell.setOnClickListener(new View.OnClickListener() { |  | ||||||
|             @Override |  | ||||||
|             public void onClick(View view) { |  | ||||||
|                 mRemoteService.setDownloadFlags(IDownloaderService.FLAGS_DOWNLOAD_OVER_CELLULAR); |  | ||||||
|                 mRemoteService.requestContinueDownload(); |  | ||||||
|                 mCellMessage.setVisibility(View.GONE); |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Called when the activity is first create; we wouldn't create a layout in |  | ||||||
|      * the case where we have the file and are moving to another activity |  | ||||||
|      * without downloading. |  | ||||||
|      */ |  | ||||||
|     @Override |  | ||||||
|     public void onCreate(Bundle savedInstanceState) { |  | ||||||
|         super.onCreate(savedInstanceState); |  | ||||||
| 		GameActivity.Log.debug("Starting DownloaderActivity..."); |  | ||||||
| 		_download = this; |  | ||||||
| 		// Create somewhere to place the output - we'll check this on 'finish' to make sure we are returning 'something' |  | ||||||
| 		OutputData = new Intent(); |  | ||||||
| 		 |  | ||||||
|         /** |  | ||||||
|          * Both downloading and validation make use of the "download" UI |  | ||||||
|          */ |  | ||||||
|         initializeDownloadUI(); |  | ||||||
| 		GameActivity.Log.debug("... UI setup. Checking for files."); |  | ||||||
| 		 |  | ||||||
|         /** |  | ||||||
|          * Before we do anything, are the files we expect already here and |  | ||||||
|          * delivered (presumably by Market) For free titles, this is probably |  | ||||||
|          * worth doing. (so no Market request is necessary) |  | ||||||
|          */ |  | ||||||
|         if (!expansionFilesDelivered()) { |  | ||||||
| 				GameActivity.Log.debug("... Whoops... missing; go go go download system!"); |  | ||||||
| 				 |  | ||||||
|             try { |  | ||||||
| 			 |  | ||||||
| 				// Make sure we have a key before we try to start the service |  | ||||||
| 				if(OBBDownloaderService.getPublicKeyLength() == 0) { |  | ||||||
| 					AlertDialog.Builder builder = new AlertDialog.Builder(this); |  | ||||||
| 				 |  | ||||||
| 					builder.setCancelable(false) |  | ||||||
| 							.setTitle("No Google Play Store Key") |  | ||||||
| 							.setMessage("No OBB found and no store key to try to download. Please set one up in Android Project Settings") |  | ||||||
| 							.setPositiveButton("Exit", new DialogInterface.OnClickListener() { |  | ||||||
| 								public void onClick(DialogInterface dialog, int item) { |  | ||||||
| 									OutputData.putExtra(GameActivity.DOWNLOAD_RETURN_NAME, GameActivity.DOWNLOAD_NO_PLAY_KEY); |  | ||||||
| 									setResult(RESULT_OK, OutputData); |  | ||||||
| 									finish(); |  | ||||||
| 								} |  | ||||||
| 							}); |  | ||||||
| 					 |  | ||||||
| 					AlertDialog alert = builder.create(); |  | ||||||
| 					alert.show(); |  | ||||||
| 				} |  | ||||||
| 				else |  | ||||||
| 				{ |  | ||||||
| 			 |  | ||||||
| 					Intent launchIntent = DownloaderActivity.this |  | ||||||
| 							.getIntent(); |  | ||||||
| 					Intent intentToLaunchThisActivityFromNotification = new Intent( |  | ||||||
| 							DownloaderActivity |  | ||||||
| 							.this, DownloaderActivity.this.getClass()); |  | ||||||
| 					intentToLaunchThisActivityFromNotification.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | |  | ||||||
| 							Intent.FLAG_ACTIVITY_CLEAR_TOP); |  | ||||||
| 					intentToLaunchThisActivityFromNotification.setAction(launchIntent.getAction()); |  | ||||||
| 
 |  | ||||||
| 					if (launchIntent.getCategories() != null) { |  | ||||||
| 						for (String category : launchIntent.getCategories()) { |  | ||||||
| 							intentToLaunchThisActivityFromNotification.addCategory(category); |  | ||||||
| 						} |  | ||||||
| 					} |  | ||||||
| 
 |  | ||||||
| 					// Build PendingIntent used to open this activity from |  | ||||||
| 					// Notification |  | ||||||
| 					PendingIntent pendingIntent = PendingIntent.getActivity( |  | ||||||
| 							DownloaderActivity.this, |  | ||||||
| 							0, intentToLaunchThisActivityFromNotification, |  | ||||||
| 							PendingIntent.FLAG_UPDATE_CURRENT); |  | ||||||
| 					// Request to start the download |  | ||||||
| 					int startResult = DownloaderClientMarshaller.startDownloadServiceIfRequired(this, |  | ||||||
| 							pendingIntent, OBBDownloaderService.class); |  | ||||||
| 
 |  | ||||||
| 					if (startResult != DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED) { |  | ||||||
| 						// The DownloaderService has started downloading the files, |  | ||||||
| 						// show progress |  | ||||||
| 						initializeDownloadUI(); |  | ||||||
| 						return; |  | ||||||
| 					} // otherwise, download not needed so we fall through to saying all is OK |  | ||||||
| 					else |  | ||||||
| 					{ |  | ||||||
| 						OutputData.putExtra(GameActivity.DOWNLOAD_RETURN_NAME, GameActivity.DOWNLOAD_FILES_PRESENT); |  | ||||||
| 						setResult(RESULT_OK, OutputData); |  | ||||||
| 						finish(); |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
|                    |  | ||||||
|             } catch (NameNotFoundException e) { |  | ||||||
|                 Log.e(LOG_TAG, "Cannot find own package! MAYDAY!"); |  | ||||||
|                 e.printStackTrace(); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|         } else { |  | ||||||
| 			GameActivity.Log.debug("... Can has! Check 'em Dano!"); |  | ||||||
| 			if(!onlySingleExpansionFileFound())	{ |  | ||||||
| 				// Do some UI here to figure out which we want to keep |  | ||||||
| 				 |  | ||||||
| 				AlertDialog.Builder builder = new AlertDialog.Builder(this); |  | ||||||
| 				 |  | ||||||
| 				builder.setCancelable(false) |  | ||||||
| 						.setTitle("Select OBB to use") |  | ||||||
| 					    .setItems(OBBSelectItems, new DialogInterface.OnClickListener() { |  | ||||||
| 							public void onClick(DialogInterface dialog, int item) { |  | ||||||
| 								DownloaderActivity.RemoveOBBFile(item); |  | ||||||
| 								ProcessOBBFiles(); |  | ||||||
| 							} |  | ||||||
| 						}); |  | ||||||
| 				 |  | ||||||
| 				AlertDialog alert = builder.create(); |  | ||||||
| 				alert.show(); |  | ||||||
| 			} |  | ||||||
| 			else { |  | ||||||
| 				ProcessOBBFiles(); |  | ||||||
| 			} |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Connect the stub to our service on start. |  | ||||||
|      */ |  | ||||||
|     @Override |  | ||||||
|     protected void onStart() { |  | ||||||
|         if (null != mDownloaderClientStub) { |  | ||||||
|             mDownloaderClientStub.connect(this); |  | ||||||
|         } |  | ||||||
|         super.onStart(); |  | ||||||
|     } |  | ||||||
| 	 |  | ||||||
| 	@Override |  | ||||||
| 	protected void onPause() { |  | ||||||
| 		super.onPause(); |  | ||||||
| 		GameActivity.Log.debug("In onPause"); |  | ||||||
| 		 |  | ||||||
| 		if(OutputData.getIntExtra(GameActivity.DOWNLOAD_RETURN_NAME, GameActivity.DOWNLOAD_NO_RETURN_CODE) == GameActivity.DOWNLOAD_NO_RETURN_CODE) |  | ||||||
| 		{ |  | ||||||
| 			GameActivity.Log.debug("onPause returning that user quit the download."); |  | ||||||
| 			OutputData.putExtra(GameActivity.DOWNLOAD_RETURN_NAME, GameActivity.DOWNLOAD_USER_QUIT); |  | ||||||
| 			setResult(RESULT_OK, OutputData); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Disconnect the stub from our service on stop |  | ||||||
|      */ |  | ||||||
|     @Override |  | ||||||
|     protected void onStop() { |  | ||||||
|         if (null != mDownloaderClientStub) { |  | ||||||
|             mDownloaderClientStub.disconnect(this); |  | ||||||
|         } |  | ||||||
|         super.onStop(); |  | ||||||
| 		setResult(RESULT_OK, OutputData); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Critical implementation detail. In onServiceConnected we create the |  | ||||||
|      * remote service and marshaler. This is how we pass the client information |  | ||||||
|      * back to the service so the client can be properly notified of changes. We |  | ||||||
|      * must do this every time we reconnect to the service. |  | ||||||
|      */ |  | ||||||
|     @Override |  | ||||||
|     public void onServiceConnected(Messenger m) { |  | ||||||
|         mRemoteService = DownloaderServiceMarshaller.CreateProxy(m); |  | ||||||
|         mRemoteService.onClientUpdated(mDownloaderClientStub.getMessenger()); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * The download state should trigger changes in the UI --- it may be useful |  | ||||||
|      * to show the state as being indeterminate at times. This sample can be |  | ||||||
|      * considered a guideline. |  | ||||||
|      */ |  | ||||||
|     @Override |  | ||||||
|     public void onDownloadStateChanged(int newState) { |  | ||||||
|         setState(newState); |  | ||||||
|         boolean showDashboard = true; |  | ||||||
|         boolean showCellMessage = false; |  | ||||||
|         boolean paused; |  | ||||||
|         boolean indeterminate; |  | ||||||
|         switch (newState) { |  | ||||||
|             case IDownloaderClient.STATE_IDLE: |  | ||||||
|                 // STATE_IDLE means the service is listening, so it's |  | ||||||
|                 // safe to start making calls via mRemoteService. |  | ||||||
|                 paused = false; |  | ||||||
|                 indeterminate = true; |  | ||||||
|                 break; |  | ||||||
|             case IDownloaderClient.STATE_CONNECTING: |  | ||||||
|             case IDownloaderClient.STATE_FETCHING_URL: |  | ||||||
|                 showDashboard = true; |  | ||||||
|                 paused = false; |  | ||||||
|                 indeterminate = true; |  | ||||||
|                 break; |  | ||||||
|             case IDownloaderClient.STATE_DOWNLOADING: |  | ||||||
|                 paused = false; |  | ||||||
|                 showDashboard = true; |  | ||||||
|                 indeterminate = false; |  | ||||||
|                 break; |  | ||||||
| 
 |  | ||||||
|             case IDownloaderClient.STATE_FAILED_CANCELED: |  | ||||||
|             case IDownloaderClient.STATE_FAILED: |  | ||||||
|             case IDownloaderClient.STATE_FAILED_FETCHING_URL: |  | ||||||
|             case IDownloaderClient.STATE_FAILED_UNLICENSED: |  | ||||||
|                 paused = true; |  | ||||||
|                 showDashboard = false; |  | ||||||
|                 indeterminate = false; |  | ||||||
|                 break; |  | ||||||
|             case IDownloaderClient.STATE_PAUSED_NEED_CELLULAR_PERMISSION: |  | ||||||
|             case IDownloaderClient.STATE_PAUSED_WIFI_DISABLED_NEED_CELLULAR_PERMISSION: |  | ||||||
|                 showDashboard = false; |  | ||||||
|                 paused = true; |  | ||||||
|                 indeterminate = false; |  | ||||||
|                 showCellMessage = true; |  | ||||||
|                 break; |  | ||||||
| 
 |  | ||||||
|             case IDownloaderClient.STATE_PAUSED_BY_REQUEST: |  | ||||||
|                 paused = true; |  | ||||||
|                 indeterminate = false; |  | ||||||
|                 break; |  | ||||||
|             case IDownloaderClient.STATE_PAUSED_ROAMING: |  | ||||||
|             case IDownloaderClient.STATE_PAUSED_SDCARD_UNAVAILABLE: |  | ||||||
|                 paused = true; |  | ||||||
|                 indeterminate = false; |  | ||||||
|                 break; |  | ||||||
|             case IDownloaderClient.STATE_COMPLETED: |  | ||||||
|                 showDashboard = false; |  | ||||||
|                 paused = false; |  | ||||||
|                 indeterminate = false; |  | ||||||
|                 validateXAPKZipFiles(); |  | ||||||
|                 return; |  | ||||||
|             default: |  | ||||||
|                 paused = true; |  | ||||||
|                 indeterminate = true; |  | ||||||
|                 showDashboard = true; |  | ||||||
|         } |  | ||||||
|         int newDashboardVisibility = showDashboard ? View.VISIBLE : View.GONE; |  | ||||||
|         if (mDashboard.getVisibility() != newDashboardVisibility) { |  | ||||||
|             mDashboard.setVisibility(newDashboardVisibility); |  | ||||||
|         } |  | ||||||
|         int cellMessageVisibility = showCellMessage ? View.VISIBLE : View.GONE; |  | ||||||
|         if (mCellMessage.getVisibility() != cellMessageVisibility) { |  | ||||||
|             mCellMessage.setVisibility(cellMessageVisibility); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         mPB.setIndeterminate(indeterminate); |  | ||||||
|         setButtonPausedState(paused); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Sets the state of the various controls based on the progressinfo object |  | ||||||
|      * sent from the downloader service. |  | ||||||
|      */ |  | ||||||
|     @Override |  | ||||||
|     public void onDownloadProgress(DownloadProgressInfo progress) { |  | ||||||
|         mAverageSpeed.setText(getString(R.string.kilobytes_per_second, |  | ||||||
|                 Helpers.getSpeedString(progress.mCurrentSpeed))); |  | ||||||
|         mTimeRemaining.setText(getString(R.string.time_remaining, |  | ||||||
|                 Helpers.getTimeRemaining(progress.mTimeRemaining))); |  | ||||||
| 
 |  | ||||||
|         progress.mOverallTotal = progress.mOverallTotal; |  | ||||||
|         mPB.setMax((int) (progress.mOverallTotal >> 8)); |  | ||||||
|         mPB.setProgress((int) (progress.mOverallProgress >> 8)); |  | ||||||
|         mProgressPercent.setText(Long.toString(progress.mOverallProgress |  | ||||||
|                 * 100 / |  | ||||||
|                 progress.mOverallTotal) + "%"); |  | ||||||
|         mProgressFraction.setText(Helpers.getDownloadProgressString |  | ||||||
|                 (progress.mOverallProgress, |  | ||||||
|                         progress.mOverallTotal)); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     protected void onDestroy() { |  | ||||||
|         this.mCancelValidation = true; |  | ||||||
|         super.onDestroy(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| @ -1,66 +0,0 @@ | |||||||
| /* |  | ||||||
|  * Copyright (C) 2012 The Android Open Source Project |  | ||||||
|  * |  | ||||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
|  * you may not use this file except in compliance with the License. |  | ||||||
|  * You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, software |  | ||||||
|  * distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
|  * See the License for the specific language governing permissions and |  | ||||||
|  * limitations under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package com.epicgames.Gallery; |  | ||||||
| 
 |  | ||||||
| import com.google.android.vending.expansion.downloader.impl.DownloaderService; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Minimal client implementation of the |  | ||||||
|  * DownloaderService from the Downloader library. |  | ||||||
|  */ |  | ||||||
| public class OBBDownloaderService extends DownloaderService { |  | ||||||
|     // stuff for LVL -- MODIFY FOR YOUR APPLICATION! |  | ||||||
|     private static final String BASE64_PUBLIC_KEY = ""; |  | ||||||
|     // used by the preference obfuscater |  | ||||||
|     private static final byte[] SALT = new byte[] { |  | ||||||
|             1, 43, -12, -1, 54, 98, |  | ||||||
|             -100, -12, 43, 2, -8, -4, 9, 5, -106, -108, -33, 45, -1, 84 |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
| 	public static int getPublicKeyLength() { |  | ||||||
| 		return BASE64_PUBLIC_KEY.length(); |  | ||||||
| 	} |  | ||||||
| 	 |  | ||||||
|     /** |  | ||||||
|      * This public key comes from your Android Market publisher account, and it |  | ||||||
|      * used by the LVL to validate responses from Market on your behalf. |  | ||||||
|      */ |  | ||||||
|     @Override |  | ||||||
|     public String getPublicKey() { |  | ||||||
|         return BASE64_PUBLIC_KEY; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * This is used by the preference obfuscater to make sure that your |  | ||||||
|      * obfuscated preferences are different than the ones used by other |  | ||||||
|      * applications. |  | ||||||
|      */ |  | ||||||
|     @Override |  | ||||||
|     public byte[] getSALT() { |  | ||||||
|         return SALT; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Fill this in with the class name for your alarm receiver. We do this |  | ||||||
|      * because receivers must be unique across all of Android (it's a good idea |  | ||||||
|      * to make sure that your receiver is in your unique package) |  | ||||||
|      */ |  | ||||||
|     @Override |  | ||||||
|     public String getAlarmReceiverClassName() { |  | ||||||
|         return com.epicgames.Gallery.AlarmReceiver.class.getName(); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,33 +0,0 @@ | |||||||
| package com.epicgames.ue4; |  | ||||||
| 
 |  | ||||||
| import com.epicgames.Gallery.OBBDownloaderService; |  | ||||||
| import com.epicgames.Gallery.DownloaderActivity; |  | ||||||
| import android.app.Activity; |  | ||||||
| import com.google.android.vending.expansion.downloader.Helpers; |  | ||||||
| import com.epicgames.Gallery.OBBData; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| public class DownloadShim |  | ||||||
| { |  | ||||||
| 	public static OBBDownloaderService DownloaderService; |  | ||||||
| 	public static DownloaderActivity DownloadActivity; |  | ||||||
| 	public static Class<DownloaderActivity> GetDownloaderType() { return DownloaderActivity.class; } |  | ||||||
| 	public static boolean expansionFilesDelivered(Activity activity, int version) { |  | ||||||
| 		for (OBBData.XAPKFile xf : OBBData.xAPKS) { |  | ||||||
| 			String fileName = Helpers.getExpansionAPKFileName(activity, xf.mIsMain, Integer.toString(version), OBBData.AppType); |  | ||||||
| 			GameActivity.Log.debug("Checking for file : " + fileName); |  | ||||||
| 			String fileForNewFile = Helpers.generateSaveFileName(activity, fileName); |  | ||||||
| 			String fileForDevFile = Helpers.generateSaveFileNameDevelopment(activity, fileName); |  | ||||||
| 			GameActivity.Log.debug("which is really being resolved to : " + fileForNewFile + "\n Or : " + fileForDevFile); |  | ||||||
| 			if (Helpers.doesFileExist(activity, fileName, xf.mFileSize, false)) { |  | ||||||
| 				GameActivity.Log.debug("Found OBB here: " + fileForNewFile); |  | ||||||
| 			} |  | ||||||
| 			else if (Helpers.doesFileExistDev(activity, fileName, xf.mFileSize, false)) { |  | ||||||
| 				GameActivity.Log.debug("Found OBB here: " + fileForDevFile); |  | ||||||
| 			} |  | ||||||
| 			else return false; |  | ||||||
| 		} |  | ||||||
| 		return true; |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| @ -77,7 +77,7 @@ vr.InstancedStereo=True | |||||||
| r.MobileHDR=False | r.MobileHDR=False | ||||||
| vr.MobileMultiView=True | vr.MobileMultiView=True | ||||||
| r.Mobile.UseHWsRGBEncoding=True | r.Mobile.UseHWsRGBEncoding=True | ||||||
| vr.RoundRobinOcclusion=True | vr.RoundRobinOcclusion=False | ||||||
| vr.ODSCapture=False | vr.ODSCapture=False | ||||||
| r.MeshStreaming=False | r.MeshStreaming=False | ||||||
| r.WireframeCullThreshold=5.000000 | r.WireframeCullThreshold=5.000000 | ||||||
| @ -115,7 +115,6 @@ VisualizeCalibrationColorMaterialPath=None | |||||||
| VisualizeCalibrationCustomMaterialPath=None | VisualizeCalibrationCustomMaterialPath=None | ||||||
| VisualizeCalibrationGrayscaleMaterialPath=None | VisualizeCalibrationGrayscaleMaterialPath=None | ||||||
| r.Mobile.SupportGPUScene=1 | r.Mobile.SupportGPUScene=1 | ||||||
| vr.VRS.HMDFixedFoveationLevel=1 |  | ||||||
| 
 | 
 | ||||||
| [/Script/HardwareTargeting.HardwareTargetingSettings] | [/Script/HardwareTargeting.HardwareTargetingSettings] | ||||||
| TargetedHardwareClass=Mobile | TargetedHardwareClass=Mobile | ||||||
| @ -133,7 +132,7 @@ ThreePlayerSplitscreenLayout=FavorTop | |||||||
| FourPlayerSplitscreenLayout=Grid | FourPlayerSplitscreenLayout=Grid | ||||||
| bOffsetPlayerGamepadIds=False | bOffsetPlayerGamepadIds=False | ||||||
| GameInstanceClass=/Script/Engine.GameInstance | GameInstanceClass=/Script/Engine.GameInstance | ||||||
| GameDefaultMap=/Game/Maps/Exhibition.Exhibition | GameDefaultMap=/Game/VRTemplate/Maps/VRTemplateMap.VRTemplateMap | ||||||
| ServerDefaultMap=/Engine/Maps/Entry.Entry | ServerDefaultMap=/Engine/Maps/Entry.Entry | ||||||
| GlobalDefaultGameMode=/Game/VRTemplate/Blueprints/VRGameMode.VRGameMode_C | GlobalDefaultGameMode=/Game/VRTemplate/Blueprints/VRGameMode.VRGameMode_C | ||||||
| GlobalDefaultServerGameMode=None | GlobalDefaultServerGameMode=None | ||||||
| @ -176,7 +175,7 @@ StoreVersionOffsetX8664=0 | |||||||
| ApplicationDisplayName= | ApplicationDisplayName= | ||||||
| VersionDisplayName=1.0 | VersionDisplayName=1.0 | ||||||
| MinSDKVersion=23 | MinSDKVersion=23 | ||||||
| TargetSDKVersion=29 | TargetSDKVersion=25 | ||||||
| InstallLocation=InternalOnly | InstallLocation=InternalOnly | ||||||
| bEnableGradle=True | bEnableGradle=True | ||||||
| bEnableLint=False | bEnableLint=False | ||||||
| @ -214,10 +213,10 @@ KeyStore=UE.keystore | |||||||
| KeyAlias=DistroKey | KeyAlias=DistroKey | ||||||
| KeyStorePassword=codesigner | KeyStorePassword=codesigner | ||||||
| KeyPassword= | KeyPassword= | ||||||
| bBuildForArmV7=False | bBuildForArmV7=True | ||||||
| bBuildForArm64=True | bBuildForArm64=False | ||||||
| bBuildForX8664=False | bBuildForX8664=False | ||||||
| bBuildForES31=False | bBuildForES31=True | ||||||
| bSupportsVulkan=True | bSupportsVulkan=True | ||||||
| bSupportsVulkanSM5=False | bSupportsVulkanSM5=False | ||||||
| ClangSanitizer=None | ClangSanitizer=None | ||||||
| @ -264,7 +263,7 @@ AutoStreamingThreshold=0.000000 | |||||||
| AndroidGraphicsDebugger=None | AndroidGraphicsDebugger=None | ||||||
| MaliGraphicsDebuggerPath=(Path="") | MaliGraphicsDebuggerPath=(Path="") | ||||||
| bEnableMaliPerfCounters=False | bEnableMaliPerfCounters=False | ||||||
| bMultiTargetFormat_ETC2=False | bMultiTargetFormat_ETC2=True | ||||||
| bMultiTargetFormat_DXT=True | bMultiTargetFormat_DXT=True | ||||||
| bMultiTargetFormat_ASTC=True | bMultiTargetFormat_ASTC=True | ||||||
| TextureFormatPriority_ETC2=0.200000 | TextureFormatPriority_ETC2=0.200000 | ||||||
| @ -349,4 +348,3 @@ FFRLevel=FFR_Medium | |||||||
| [/Script/Engine.Engine] | [/Script/Engine.Engine] | ||||||
| +ActiveGameNameRedirects=(OldGameName="TP_VirtualRealityBP",NewGameName="/Script/Gallery") | +ActiveGameNameRedirects=(OldGameName="TP_VirtualRealityBP",NewGameName="/Script/Gallery") | ||||||
| +ActiveGameNameRedirects=(OldGameName="/Script/TP_VirtualRealityBP",NewGameName="/Script/Gallery") | +ActiveGameNameRedirects=(OldGameName="/Script/TP_VirtualRealityBP",NewGameName="/Script/Gallery") | ||||||
| 
 |  | ||||||
|  | |||||||
| @ -2,76 +2,3 @@ | |||||||
| ProjectID=91407DA546A55FB46A0ED68419EBF86D | ProjectID=91407DA546A55FB46A0ED68419EBF86D | ||||||
| bStartInVR=True | bStartInVR=True | ||||||
| 
 | 
 | ||||||
| [/Script/UnrealEd.ProjectPackagingSettings] |  | ||||||
| Build=IfProjectHasCode |  | ||||||
| BuildConfiguration=PPBC_Development |  | ||||||
| BuildTarget= |  | ||||||
| StagingDirectory=(Path="D:/Unreal Projects/Builds/build5") |  | ||||||
| FullRebuild=False |  | ||||||
| ForDistribution=False |  | ||||||
| IncludeDebugFiles=False |  | ||||||
| BlueprintNativizationMethod=Disabled |  | ||||||
| bIncludeNativizedAssetsInProjectGeneration=False |  | ||||||
| bExcludeMonolithicEngineHeadersInNativizedCode=False |  | ||||||
| UsePakFile=True |  | ||||||
| bUseIoStore=False |  | ||||||
| bMakeBinaryConfig=False |  | ||||||
| bGenerateChunks=False |  | ||||||
| bGenerateNoChunks=False |  | ||||||
| bChunkHardReferencesOnly=False |  | ||||||
| bForceOneChunkPerFile=False |  | ||||||
| MaxChunkSize=0 |  | ||||||
| bBuildHttpChunkInstallData=False |  | ||||||
| HttpChunkInstallDataDirectory=(Path="") |  | ||||||
| bCompressed=True |  | ||||||
| PakFileCompressionFormats=Oodle |  | ||||||
| bForceUseProjectCompressionFormatIgnoreHardwareOverride=False |  | ||||||
| PakFileAdditionalCompressionOptions=-compressionblocksize=256KB |  | ||||||
| PakFileCompressionMethod=Kraken |  | ||||||
| PakFileCompressionLevel_DebugDevelopment=3 |  | ||||||
| PakFileCompressionLevel_TestShipping=5 |  | ||||||
| PakFileCompressionLevel_Distribution=7 |  | ||||||
| HttpChunkInstallDataVersion= |  | ||||||
| IncludePrerequisites=True |  | ||||||
| IncludeAppLocalPrerequisites=False |  | ||||||
| bShareMaterialShaderCode=True |  | ||||||
| bDeterministicShaderCodeOrder=False |  | ||||||
| bSharedMaterialNativeLibraries=True |  | ||||||
| ApplocalPrerequisitesDirectory=(Path="") |  | ||||||
| IncludeCrashReporter=False |  | ||||||
| InternationalizationPreset=English |  | ||||||
| -CulturesToStage=en |  | ||||||
| +CulturesToStage=en |  | ||||||
| LocalizationTargetCatchAllChunkId=0 |  | ||||||
| bCookAll=False |  | ||||||
| bCookMapsOnly=False |  | ||||||
| bSkipEditorContent=False |  | ||||||
| bSkipMovies=False |  | ||||||
| -IniKeyBlacklist=KeyStorePassword |  | ||||||
| -IniKeyBlacklist=KeyPassword |  | ||||||
| -IniKeyBlacklist=rsa.privateexp |  | ||||||
| -IniKeyBlacklist=rsa.modulus |  | ||||||
| -IniKeyBlacklist=rsa.publicexp |  | ||||||
| -IniKeyBlacklist=aes.key |  | ||||||
| -IniKeyBlacklist=SigningPublicExponent |  | ||||||
| -IniKeyBlacklist=SigningModulus |  | ||||||
| -IniKeyBlacklist=SigningPrivateExponent |  | ||||||
| -IniKeyBlacklist=EncryptionKey |  | ||||||
| -IniKeyBlacklist=IniKeyBlacklist |  | ||||||
| -IniKeyBlacklist=IniSectionBlacklist |  | ||||||
| +IniKeyBlacklist=KeyStorePassword |  | ||||||
| +IniKeyBlacklist=KeyPassword |  | ||||||
| +IniKeyBlacklist=rsa.privateexp |  | ||||||
| +IniKeyBlacklist=rsa.modulus |  | ||||||
| +IniKeyBlacklist=rsa.publicexp |  | ||||||
| +IniKeyBlacklist=aes.key |  | ||||||
| +IniKeyBlacklist=SigningPublicExponent |  | ||||||
| +IniKeyBlacklist=SigningModulus |  | ||||||
| +IniKeyBlacklist=SigningPrivateExponent |  | ||||||
| +IniKeyBlacklist=EncryptionKey |  | ||||||
| +IniKeyBlacklist=IniKeyBlacklist |  | ||||||
| +IniKeyBlacklist=IniSectionBlacklist |  | ||||||
| +MapsToCook=(FilePath="/Game/Maps/Gallery") |  | ||||||
| +MapsToCook=(FilePath="/Game/Maps/Exhibition") |  | ||||||
| +MapsToCook=(FilePath="/Game/VRTemplate/Maps/VRTemplateMap") |  | ||||||
| 
 |  | ||||||
|  | |||||||
| @ -142,6 +142,12 @@ DoubleClickTime=0.200000 | |||||||
| +ActionMappings=(ActionName="MenuToggleRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=ValveIndex_Right_System_Click) | +ActionMappings=(ActionName="MenuToggleRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=ValveIndex_Right_System_Click) | ||||||
| +ActionMappings=(ActionName="MenuToggleRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=MixedReality_Right_Menu_Click) | +ActionMappings=(ActionName="MenuToggleRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=MixedReality_Right_Menu_Click) | ||||||
| +ActionMappings=(ActionName="MenuToggleRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Vive_Right_Menu_Click) | +ActionMappings=(ActionName="MenuToggleRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Vive_Right_Menu_Click) | ||||||
|  | +ActionMappings=(ActionName="GrabPullLeft",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=OculusTouch_Left_Y_Click) | ||||||
|  | +ActionMappings=(ActionName="GrabPullRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=RightMouseButton) | ||||||
|  | +ActionMappings=(ActionName="ScaleWorldUp",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=OculusTouch_Right_A_Click) | ||||||
|  | +ActionMappings=(ActionName="ScaleWorldUp",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=X) | ||||||
|  | +ActionMappings=(ActionName="ScaleWorldDown",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Z) | ||||||
|  | +ActionMappings=(ActionName="ScaleWorldDown",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=OculusTouch_Right_B_Click) | ||||||
| +AxisMappings=(AxisName="MovementAxisLeft_X",Scale=1.000000,Key=OculusTouch_Left_Thumbstick_X) | +AxisMappings=(AxisName="MovementAxisLeft_X",Scale=1.000000,Key=OculusTouch_Left_Thumbstick_X) | ||||||
| +AxisMappings=(AxisName="GrabAxisLeft",Scale=1.000000,Key=OculusTouch_Left_Grip_Axis) | +AxisMappings=(AxisName="GrabAxisLeft",Scale=1.000000,Key=OculusTouch_Left_Grip_Axis) | ||||||
| +AxisMappings=(AxisName="MovementAxisLeft_Y",Scale=1.000000,Key=OculusTouch_Left_Thumbstick_Y) | +AxisMappings=(AxisName="MovementAxisLeft_Y",Scale=1.000000,Key=OculusTouch_Left_Thumbstick_Y) | ||||||
| @ -184,8 +190,9 @@ DoubleClickTime=0.200000 | |||||||
| +AxisMappings=(AxisName="MovementAxisRight_Y",Scale=1.000000,Key=ValveIndex_Right_Thumbstick_Y) | +AxisMappings=(AxisName="MovementAxisRight_Y",Scale=1.000000,Key=ValveIndex_Right_Thumbstick_Y) | ||||||
| +AxisMappings=(AxisName="MovementAxisRight_Y",Scale=1.000000,Key=MixedReality_Right_Thumbstick_Y) | +AxisMappings=(AxisName="MovementAxisRight_Y",Scale=1.000000,Key=MixedReality_Right_Thumbstick_Y) | ||||||
| +AxisMappings=(AxisName="MovementAxisRight_Y",Scale=1.000000,Key=Vive_Right_Trackpad_Y) | +AxisMappings=(AxisName="MovementAxisRight_Y",Scale=1.000000,Key=Vive_Right_Trackpad_Y) | ||||||
| +AxisMappings=(AxisName="MovementAxisRight_Y",Scale=1.000000,Key=OculusTouch_Right_A_Click) |  | ||||||
| +AxisMappings=(AxisName="TeleportationAxis",Scale=1.000000,Key=OculusTouch_Right_A_Click) | +AxisMappings=(AxisName="TeleportationAxis",Scale=1.000000,Key=OculusTouch_Right_A_Click) | ||||||
|  | +AxisMappings=(AxisName="MovementAxisRight_Y",Scale=1.000000,Key=D) | ||||||
|  | +AxisMappings=(AxisName="MovementAxisRight_X",Scale=1.000000,Key=A) | ||||||
| DefaultPlayerInputClass=/Script/Engine.PlayerInput | DefaultPlayerInputClass=/Script/Engine.PlayerInput | ||||||
| DefaultInputComponentClass=/Script/Engine.InputComponent | DefaultInputComponentClass=/Script/Engine.InputComponent | ||||||
| DefaultTouchInterface=None | DefaultTouchInterface=None | ||||||
|  | |||||||