wineandroid: Install libraries from the package assets if present.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
93d4ac2a0f
commit
da2522becb
|
@ -8,4 +8,9 @@ EXTRA_TARGETS = wine-debug.apk
|
|||
all: wine-debug.apk
|
||||
|
||||
wine-debug.apk: build.gradle $(srcdir)/AndroidManifest.xml $(srcdir)/WineActivity.java $(srcdir)/wine.svg
|
||||
(test -d assets && \
|
||||
rm -f assets/files.sum assets/sums.sum && \
|
||||
sha256sum `find assets -type f -print` | sed 's/ assets\// /' >files.sum && \
|
||||
sha256sum files.sum >sums.sum && \
|
||||
mv files.sum sums.sum assets) || rm -rf assets
|
||||
gradle -q assembleDebug && mv build/outputs/apk/wine-debug.apk .
|
||||
|
|
|
@ -21,13 +21,177 @@
|
|||
package org.winehq.wine;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class WineActivity extends Activity
|
||||
{
|
||||
private final String LOGTAG = "wine";
|
||||
private ProgressDialog progress_dialog;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate( savedInstanceState );
|
||||
|
||||
requestWindowFeature( android.view.Window.FEATURE_NO_TITLE );
|
||||
|
||||
new Thread( new Runnable() { public void run() { loadWine(); }} ).start();
|
||||
}
|
||||
|
||||
private void loadWine()
|
||||
{
|
||||
copyAssetFiles();
|
||||
runOnUiThread( new Runnable() { public void run() { progress_dialog.dismiss(); }});
|
||||
}
|
||||
|
||||
private void createProgressDialog( final int max, final String message )
|
||||
{
|
||||
runOnUiThread( new Runnable() { public void run() {
|
||||
if (progress_dialog != null) progress_dialog.dismiss();
|
||||
progress_dialog = new ProgressDialog( WineActivity.this );
|
||||
progress_dialog.setProgressStyle( max > 0 ? ProgressDialog.STYLE_HORIZONTAL
|
||||
: ProgressDialog.STYLE_SPINNER );
|
||||
progress_dialog.setTitle( "Wine" );
|
||||
progress_dialog.setMessage( message );
|
||||
progress_dialog.setCancelable( false );
|
||||
progress_dialog.setMax( max );
|
||||
progress_dialog.show();
|
||||
}});
|
||||
|
||||
}
|
||||
|
||||
private final boolean isFileWanted( String name )
|
||||
{
|
||||
if (name.equals( "files.sum" )) return true;
|
||||
if (name.startsWith( "share/" )) return true;
|
||||
if (name.startsWith( Build.CPU_ABI + "/system/" )) return false;
|
||||
if (name.startsWith( Build.CPU_ABI + "/" )) return true;
|
||||
if (name.startsWith( "x86/" )) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private final boolean isFileExecutable( String name )
|
||||
{
|
||||
return name.startsWith( Build.CPU_ABI + "/" ) || name.startsWith( "x86/" );
|
||||
}
|
||||
|
||||
private final HashMap<String,String> readMapFromInputStream( InputStream in )
|
||||
{
|
||||
HashMap<String,String> map = new HashMap<String,String>();
|
||||
String str;
|
||||
|
||||
try
|
||||
{
|
||||
BufferedReader reader = new BufferedReader( new InputStreamReader( in, "UTF-8" ));
|
||||
while ((str = reader.readLine()) != null)
|
||||
{
|
||||
String entry[] = str.split( "\\s+", 2 );
|
||||
if (entry.length == 2 && isFileWanted( entry[1] )) map.put( entry[1], entry[0] );
|
||||
}
|
||||
}
|
||||
catch( IOException e ) { }
|
||||
return map;
|
||||
}
|
||||
|
||||
private final HashMap<String,String> readMapFromDiskFile( String file )
|
||||
{
|
||||
try
|
||||
{
|
||||
return readMapFromInputStream( new FileInputStream( new File( getFilesDir(), file )));
|
||||
}
|
||||
catch( IOException e ) { return new HashMap<String,String>(); }
|
||||
}
|
||||
|
||||
private final HashMap<String,String> readMapFromAssetFile( String file )
|
||||
{
|
||||
try
|
||||
{
|
||||
return readMapFromInputStream( getAssets().open( file ) );
|
||||
}
|
||||
catch( IOException e ) { return new HashMap<String,String>(); }
|
||||
}
|
||||
|
||||
private final void copyAssetFile( String src )
|
||||
{
|
||||
File dest = new File( getFilesDir(), src );
|
||||
try
|
||||
{
|
||||
Log.i( LOGTAG, "extracting " + dest );
|
||||
dest.getParentFile().mkdirs();
|
||||
dest.delete();
|
||||
if (dest.createNewFile())
|
||||
{
|
||||
InputStream in = getAssets().open( src );
|
||||
FileOutputStream out = new FileOutputStream( dest );
|
||||
int read;
|
||||
byte[] buffer = new byte[65536];
|
||||
|
||||
while ((read = in.read( buffer )) > 0) out.write( buffer, 0, read );
|
||||
out.close();
|
||||
if (isFileExecutable( src )) dest.setExecutable( true, true );
|
||||
}
|
||||
else
|
||||
Log.i( LOGTAG, "Failed to create file " + dest );
|
||||
}
|
||||
catch( IOException e )
|
||||
{
|
||||
Log.i( LOGTAG, "Failed to copy asset file to " + dest );
|
||||
dest.delete();
|
||||
}
|
||||
}
|
||||
|
||||
private final void deleteAssetFile( String src )
|
||||
{
|
||||
File dest = new File( getFilesDir(), src );
|
||||
Log.i( LOGTAG, "deleting " + dest );
|
||||
dest.delete();
|
||||
}
|
||||
|
||||
private final void copyAssetFiles()
|
||||
{
|
||||
String new_sum = readMapFromAssetFile( "sums.sum" ).get( "files.sum" );
|
||||
if (new_sum == null) return; // no assets
|
||||
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences( this );
|
||||
String old_sum = prefs.getString( "files.sum", "" );
|
||||
if (old_sum.equals( new_sum )) return; // no change
|
||||
prefs.edit().putString( "files.sum", new_sum ).apply();
|
||||
|
||||
HashMap<String,String> existing_files = readMapFromDiskFile( "files.sum" );
|
||||
HashMap<String,String> new_files = readMapFromAssetFile( "files.sum" );
|
||||
ArrayList<String> copy_files = new ArrayList<String>();
|
||||
copy_files.add( "files.sum" );
|
||||
|
||||
for (Map.Entry<String, String> entry : new_files.entrySet())
|
||||
{
|
||||
String name = entry.getKey();
|
||||
if (!entry.getValue().equals( existing_files.remove( name ))) copy_files.add( name );
|
||||
}
|
||||
|
||||
createProgressDialog( copy_files.size(), "Extracting files..." );
|
||||
|
||||
for (String name : existing_files.keySet()) deleteAssetFile( name );
|
||||
|
||||
for (String name : copy_files)
|
||||
{
|
||||
copyAssetFile( name );
|
||||
runOnUiThread( new Runnable() { public void run() {
|
||||
progress_dialog.incrementProgressBy( 1 ); }});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue