diff --git a/res/values/strings.xml b/res/values/strings.xml
index 1e0eb580..31453e15 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -61,12 +61,12 @@
Write test has failed
- Move your game files somewhere else, for example Android/data/%s or internal memory. At next run I will ask you about folder again.
+ Move your game files somewhere else, for example Android/data/in.celest.xash3d.hl or internal memory. At next run I will ask you about folder again.
Due to writing politics of newer Android versions, you need to select a root folder of storage where game data is located.
Select folder
Write test has been failed twice.
- Due to writing politics of Android 4.4, you can't use this storage.
+ Due to writing politics of Android 4.4, you can\'t use this storage.
Seems you have read-only filesystem.
diff --git a/src/in/celest/xash3d/CertCheck.java b/src/in/celest/xash3d/CertCheck.java
new file mode 100644
index 00000000..25a82a37
--- /dev/null
+++ b/src/in/celest/xash3d/CertCheck.java
@@ -0,0 +1,72 @@
+ package in.celest.xash3d;
+
+import android.content.*;
+import android.view.*;
+import android.os.*;
+import android.util.*;
+import android.graphics.*;
+import android.text.method.*;
+import android.text.*;
+import android.media.*;
+import android.hardware.*;
+import android.content.*;
+import android.widget.*;
+import android.content.pm.*;
+
+import java.lang.*;
+import java.util.List;
+import java.security.MessageDigest;
+
+import in.celest.xash3d.hl.BuildConfig;
+import in.celest.xash3d.XashConfig;
+
+public class CertCheck
+{
+ // Certificate checking
+ private static String SIG = "DMsE8f5hlR7211D8uehbFpbA0n8=";
+ private static String SIG_TEST = ""; // a1ba: mittorn, add your signature later
+
+ private static String TAG = "XASH3D:CertCheck";
+
+ public static boolean dumbAntiPDALifeCheck( Context context )
+ {
+ if( BuildConfig.DEBUG ||
+ !XashConfig.CHECK_SIGNATURES )
+ return false; // disable checking for debug builds
+
+ try
+ {
+ PackageInfo info = context.getPackageManager()
+ .getPackageInfo( context.getPackageName(), PackageManager.GET_SIGNATURES );
+
+ for( Signature signature: info.signatures )
+ {
+ MessageDigest md = MessageDigest.getInstance( "SHA" );
+ final byte[] signatureBytes = signature.toByteArray();
+
+ md.update( signatureBytes );
+
+ final String curSIG = Base64.encodeToString( md.digest(), Base64.NO_WRAP );
+
+ if( XashConfig.PKG_TEST )
+ {
+ if( SIG_TEST.equals(curSIG) )
+ return false;
+ }
+ else
+ {
+ if( SIG.equals(curSIG) )
+ return false;
+ }
+ }
+ }
+ catch( Exception e )
+ {
+ e.printStackTrace();
+ }
+
+ Log.e(TAG, "Please, don't resign our public release builds!");
+ Log.e(TAG, "If you want to insert some features, rebuild package with ANOTHER package name from git repository.");
+ return true;
+ }
+}
diff --git a/src/in/celest/xash3d/LauncherActivity.java b/src/in/celest/xash3d/LauncherActivity.java
index 29b0feb3..7ca0c6f8 100644
--- a/src/in/celest/xash3d/LauncherActivity.java
+++ b/src/in/celest/xash3d/LauncherActivity.java
@@ -55,6 +55,7 @@ import org.json.*;
import in.celest.xash3d.hl.R;
import in.celest.xash3d.XashActivity;
+import in.celest.xash3d.CertCheck;
public class LauncherActivity extends Activity {
// public final static String ARGV = "in.celest.xash3d.MESSAGE";
@@ -89,7 +90,7 @@ public class LauncherActivity extends Activity {
super.setTheme( 0x01030224 );
else super.setTheme( 0x01030005 );
- if( XashActivity.dumbAntiPDALifeCheck( this ) )
+ if( CertCheck.dumbAntiPDALifeCheck( this ) )
{
finish();
return;
diff --git a/src/in/celest/xash3d/XashActivity.java b/src/in/celest/xash3d/XashActivity.java
index bfabac43..4b7f45cb 100644
--- a/src/in/celest/xash3d/XashActivity.java
+++ b/src/in/celest/xash3d/XashActivity.java
@@ -19,6 +19,9 @@ import android.hardware.*;
import android.content.*;
import android.widget.*;
import android.content.pm.*;
+import android.net.Uri;
+import android.provider.*;
+import android.database.*;
import android.view.inputmethod.*;
@@ -26,9 +29,11 @@ import java.lang.*;
import java.util.List;
import java.security.MessageDigest;
+import in.celest.xash3d.hl.R;
import in.celest.xash3d.hl.BuildConfig;
import in.celest.xash3d.XashConfig;
import in.celest.xash3d.JoystickHandler;
+import in.celest.xash3d.CertCheck;
/**
Xash Activity
@@ -47,12 +52,15 @@ public class XashActivity extends Activity {
public static JoystickHandler handler;
public static ImmersiveMode mImmersiveMode;
public static boolean keyboardVisible = false;
+ public static boolean mEngineReady = false;
private static Vibrator mVibrator;
private static boolean mHasVibrator;
+ private int mReturingWithResultCode = 0;
private static int OPEN_DOCUMENT_TREE_RESULT = 1;
private static int FPICKER_RESULT = 2;
+
// Joystick constants
public final static byte JOY_HAT_CENTERED = 0; // bitmasks for hat current status
@@ -73,9 +81,6 @@ public class XashActivity extends Activity {
private static boolean mUseVolume;
public static View mDecorView;
- // Certificate checking
- private static String SIG = "DMsE8f5hlR7211D8uehbFpbA0n8=";
- private static String SIG_TEST = ""; // a1ba: mittorn, add your signature later
// Load the .so
static {
@@ -83,56 +88,15 @@ public class XashActivity extends Activity {
System.loadLibrary("xash");
}
- // Shared between this activity and LauncherActivity
- public static boolean dumbAntiPDALifeCheck( Context context )
- {
- if( BuildConfig.DEBUG ||
- !XashConfig.CHECK_SIGNATURES )
- return false; // disable checking for debug builds
-
- try
- {
- PackageInfo info = context.getPackageManager()
- .getPackageInfo( context.getPackageName(), PackageManager.GET_SIGNATURES );
-
- for( Signature signature: info.signatures )
- {
- MessageDigest md = MessageDigest.getInstance( "SHA" );
- final byte[] signatureBytes = signature.toByteArray();
-
- md.update( signatureBytes );
-
- final String curSIG = Base64.encodeToString( md.digest(), Base64.NO_WRAP );
-
- if( XashConfig.PKG_TEST )
- {
- if( SIG_TEST.equals(curSIG) )
- return false;
- }
- else
- {
- if( SIG.equals(curSIG) )
- return false;
- }
- }
- }
- catch( Exception e )
- {
- e.printStackTrace();
- }
-
- Log.e(TAG, "Please, don't resign our public release builds!");
- Log.e(TAG, "If you want to insert some features, rebuild package with ANOTHER package name from git repository.");
- return true;
- }
// Setup
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.v(TAG, "onCreate()");
super.onCreate(savedInstanceState);
+ mEngineReady = false;
- if( dumbAntiPDALifeCheck(this) )
+ if( CertCheck.dumbAntiPDALifeCheck(this) )
{
finish();
return;
@@ -170,27 +134,6 @@ public class XashActivity extends Activity {
checkWritePermission( basedir );
}
-
- if( sdk < 12 )
- handler = new JoystickHandler();
- else
- handler = new JoystickHandler_v12();
- handler.init();
-
- mPixelFormat = mPref.getInt("pixelformat", 0);
- mUseVolume = mPref.getBoolean("usevolume", false);
- if( mPref.getBoolean("enableResizeWorkaround", true) )
- AndroidBug5497Workaround.assistActivity(this);
-
- // Immersive Mode is available only at >KitKat
- Boolean enableImmersive = (sdk >= 19) && (mPref.getBoolean("immersive_mode", true));
- if( enableImmersive )
- mImmersiveMode = new ImmersiveMode_v19();
-
- mDecorView = getWindow().getDecorView();
-
- mVibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
- mHasVibrator = ( mVibrator != null ) && ( mVibrator.hasVibrator() );
}
@Override
@@ -198,43 +141,145 @@ public class XashActivity extends Activity {
{
if( resultCode != RESULT_OK )
{
- Log.v(TAG, "onActivityResult: result is not OK. Code: " + requestCode + ". Will exit now");
- finish();
+ Log.v(TAG, "onActivityResult: result is not OK. ReqCode: " + requestCode + ". ResCode: " + resultCode);
}
-
- if( requestCode == FPICKER_RESULT )
+ else
{
- String newBaseDir = resultData.getStringExtra("GetPath");
- setNewBasedir( newBaseDir );
- setFolderAsk( false ); // don't ask on next run
- checkWritePermission( newBaseDir );
- }
- else if( requestCode == OPEN_DOCUMENT_TREE_RESULT )
- {
- String basedir = getStringExtraFromIntent( getIntent(), "basedir", mPref.getString("basedir","/sdcard/xash/"));
-
- if( !nativeTestWritePermission( basedir ) )
+ // it's not possible to create dialogs here
+ // so most work will be done after Activity resuming, in onPostResume()
+ mReturingWithResultCode = requestCode;
+ if( requestCode == FPICKER_RESULT )
{
- String msg = getString(R.string.lollipop_request_permission_fail_msg) + getString(R.string.ask_about_new_basedir_msg);
-
- new AlertDialog.Builder(this)
- .setTitle( R.string.write_failed )
- .setMessage( msg )
- .setPositiveButton( R.string.ok, new DialogInterface.OnClickListener()
- {
- public void onClick(DialogInterface dialog, int whichButton)
- {
- XashActivity act = (XashActivity)getActivity();
- act.setFolderAsk( true );
- act.finish();
- }
- })
- .setCancelable(false)
- .show();
+ String newBaseDir = resultData.getStringExtra("GetPath");
+ setNewBasedir( newBaseDir );
+ setFolderAsk( false ); // don't ask on next run
+ Log.v(TAG, "Got new basedir from FPicker: " + newBaseDir );
+ }
+ else if( requestCode == OPEN_DOCUMENT_TREE_RESULT )
+ {
+ Uri uri = resultData.getData();
+ if( uri != null )
+ {
+ getContentResolver().takePersistableUriPermission(uri,
+ Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION );
+ }
}
}
}
+ @Override
+ public void onPostResume()
+ {
+ super.onPostResume();
+
+ if( mReturingWithResultCode != 0 )
+ {
+ if( mReturingWithResultCode == FPICKER_RESULT )
+ {
+ String basedir = mPref.getString( "basedir", "/sdcard/xash/" );
+ checkWritePermission( basedir );
+ }
+ else if( mReturingWithResultCode == OPEN_DOCUMENT_TREE_RESULT )
+ {
+ String basedir = getStringExtraFromIntent( getIntent(), "basedir", mPref.getString("basedir","/sdcard/xash/"));
+ Log.v(TAG, "Got permissions. Checking writing again...");
+
+ if( nativeTestWritePermission( basedir ) == 0 )
+ {
+ Log.v(TAG, "Write test has failed twice!");
+ String msg = getString(R.string.lollipop_request_permission_fail_msg) + getString(R.string.ask_about_new_basedir_msg);
+
+ new AlertDialog.Builder(this)
+ .setTitle( R.string.write_failed )
+ .setMessage( msg )
+ .setPositiveButton( R.string.ok, new DialogInterface.OnClickListener()
+ {
+ public void onClick(DialogInterface dialog, int whichButton)
+ {
+ XashActivity act = XashActivity.this;
+ act.setFolderAsk( true );
+ act.finish();
+ }
+ })
+ .setCancelable(false)
+ .show();
+ }
+ else
+ {
+ launchSurfaceAndEngine();
+ }
+ }
+
+ mReturingWithResultCode = 0;
+ }
+ }
+
+ // Events
+ @Override
+ protected void onPause() {
+ Log.v(TAG, "onPause()");
+
+ if( mEngineReady )
+ {
+ // let engine save all configs before exiting.
+ nativeOnPause();
+
+ // wait until Xash will save all configs
+ mSurface.engineThreadWait();
+
+ }
+
+ super.onPause();
+ }
+
+ @Override
+ protected void onResume() {
+ Log.v(TAG, "onResume()");
+ super.onResume();
+ }
+
+ @Override
+ protected void onStop() {
+ Log.v(TAG, "onStop()");
+
+ if( mEngineReady )
+ {
+ // let engine properly exit, instead of killing it's thread
+ nativeOnStop();
+
+ // wait for engine
+ mSurface.engineThreadWait();
+ }
+
+ super.onStop();
+ }
+
+ @Override
+ protected void onDestroy() {
+ Log.v(TAG, "onStop()");
+
+ if( mEngineReady )
+ {
+ // let engine a chance to properly exit
+ nativeOnDestroy();
+
+ // wait until Xash will exit
+ mSurface.engineThreadJoin();
+ }
+
+
+ super.onDestroy();
+ }
+
+ @Override
+ public void onWindowFocusChanged(boolean hasFocus)
+ {
+ super.onWindowFocusChanged(hasFocus);
+
+ if( mImmersiveMode != null )
+ mImmersiveMode.apply();
+ }
+
public void setFolderAsk( Boolean b )
{
SharedPreferences.Editor editor = mPref.edit();
@@ -247,7 +292,7 @@ public class XashActivity extends Activity {
{
SharedPreferences.Editor editor = mPref.edit();
- editor.putBoolean( "basedir", baseDir );
+ editor.putString( "basedir", baseDir );
editor.commit();
}
@@ -261,10 +306,12 @@ public class XashActivity extends Activity {
private void checkWritePermission( String basedir )
{
- if( !nativeTestWritePermission( basedir ) )
+ Log.v(TAG, "Checking write permissions...");
+
+ if( nativeTestWritePermission( basedir ) == 0 )
{
- Object lock = new Object;
-
+ Log.v(TAG, "First check has failed!");
+
if( sdk > 20 )
{
// OPEN_DOCUMENT_TREE
@@ -278,8 +325,7 @@ public class XashActivity extends Activity {
public void onClick(DialogInterface dialog, int whichButton)
{
Intent intent = new Intent("android.intent.action.OPEN_DOCUMENT_TREE");
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- getActivity().startActivityForResult(intent, OPEN_DOCUMENT_TREE_RESULT);
+ XashActivity.this.startActivityForResult(intent, OPEN_DOCUMENT_TREE_RESULT);
}
})
.setCancelable(false)
@@ -297,7 +343,7 @@ public class XashActivity extends Activity {
{
public void onClick(DialogInterface dialog, int whichButton)
{
- XashActivity act = (XashActivity)getActivity();
+ XashActivity act = XashActivity.this;
act.setFolderAsk( true );
act.finish();
}
@@ -318,7 +364,7 @@ public class XashActivity extends Activity {
{
public void onClick(DialogInterface dialog, int whichButton)
{
- XashActivity act = (XashActivity)getActivity();
+ XashActivity act = XashActivity.this;
act.setFolderAsk( true );
act.finish();
}
@@ -336,10 +382,11 @@ public class XashActivity extends Activity {
private void launchSurfaceAndEngine()
{
+ Log.v(TAG, "Everything is OK. Launching engine...");
+
setupEnvironment();
InstallReceiver.extractPAK(this, false);
-
// Set up the surface
mSurface = new EngineSurface(getApplication());
@@ -350,6 +397,28 @@ public class XashActivity extends Activity {
SurfaceHolder holder = mSurface.getHolder();
holder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
+ if( sdk < 12 )
+ handler = new JoystickHandler();
+ else
+ handler = new JoystickHandler_v12();
+ handler.init();
+
+ mPixelFormat = mPref.getInt("pixelformat", 0);
+ mUseVolume = mPref.getBoolean("usevolume", false);
+ if( mPref.getBoolean("enableResizeWorkaround", true) )
+ AndroidBug5497Workaround.assistActivity(this);
+
+ // Immersive Mode is available only at >KitKat
+ Boolean enableImmersive = (sdk >= 19) && (mPref.getBoolean("immersive_mode", true));
+ if( enableImmersive )
+ mImmersiveMode = new ImmersiveMode_v19();
+
+ mDecorView = getWindow().getDecorView();
+
+ mVibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
+ mHasVibrator = ( mVibrator != null ) && ( mVibrator.hasVibrator() );
+
+ mEngineReady = true;
}
private void setupEnvironment()
@@ -390,61 +459,7 @@ public class XashActivity extends Activity {
}
}
}
-
- // Events
- @Override
- protected void onPause() {
- Log.v(TAG, "onPause()");
-
- // let engine save all configs before exiting.
- nativeOnPause();
-
- // wait until Xash will save all configs
- mSurface.engineThreadWait();
- super.onPause();
- }
-
- @Override
- protected void onResume() {
- Log.v(TAG, "onResume()");
- super.onResume();
- }
-
- @Override
- protected void onStop() {
- Log.v(TAG, "onStop()");
-
- // let engine properly exit, instead of killing it's thread
- nativeOnStop();
-
- // wait for engine
- mSurface.engineThreadWait();
-
- super.onStop();
- }
-
- @Override
- protected void onDestroy() {
- Log.v(TAG, "onStop()");
-
- // let engine a chance to properly exit
- nativeOnDestroy();
-
- // wait until Xash will exit
- mSurface.engineThreadJoin();
-
- super.onDestroy();
- }
-
- @Override
- public void onWindowFocusChanged(boolean hasFocus)
- {
- super.onWindowFocusChanged(hasFocus);
-
- if( mImmersiveMode != null )
- mImmersiveMode.apply();
- }
public static native int nativeInit(Object arguments);
public static native void nativeQuit();