From 40ba22631bbb7fc4c6b88d01402e132dbaceaf2b Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Fri, 8 Jan 2016 17:53:00 -0300 Subject: Renamed godot domain from com.android.godot (which was incorrect) to org.godotengine.godot --- .../java/src/org/godotengine/godot/Godot.java | 925 +++++++++++++++++++++ 1 file changed, 925 insertions(+) create mode 100644 platform/android/java/src/org/godotengine/godot/Godot.java (limited to 'platform/android/java/src/org/godotengine/godot/Godot.java') diff --git a/platform/android/java/src/org/godotengine/godot/Godot.java b/platform/android/java/src/org/godotengine/godot/Godot.java new file mode 100644 index 000000000..6aa5d24f1 --- /dev/null +++ b/platform/android/java/src/org/godotengine/godot/Godot.java @@ -0,0 +1,925 @@ +/*************************************************************************/ +/* Godot.java */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +package org.godotengine.godot; + +import android.R; +import android.app.Activity; +import android.os.Bundle; +import android.view.MotionEvent; +import android.view.View; +import android.widget.Button; +import android.widget.ProgressBar; +import android.widget.RelativeLayout; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.view.ViewGroup.LayoutParams; +import android.app.*; +import android.content.*; +import android.content.SharedPreferences.Editor; +import android.view.*; +import android.view.inputmethod.InputMethodManager; +import android.os.*; +import android.util.Log; +import android.graphics.*; +import android.text.method.*; +import android.text.*; +import android.media.*; +import android.hardware.*; +import android.content.*; +import android.content.pm.PackageManager.NameNotFoundException; +import android.net.Uri; +import android.media.MediaPlayer; + +import java.lang.reflect.Method; +import java.util.List; +import java.util.ArrayList; + +import org.godotengine.godot.payments.PaymentsManager; + +import java.io.IOException; + +import android.provider.Settings.Secure; +import android.widget.FrameLayout; + +import org.godotengine.godot.input.*; + +import java.io.InputStream; +import javax.microedition.khronos.opengles.GL10; +import java.security.MessageDigest; +import java.io.File; +import java.io.FileInputStream; +import java.util.LinkedList; + +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.os.Bundle; +import android.os.Messenger; +import android.os.SystemClock; + + +public class Godot extends Activity implements SensorEventListener, IDownloaderClient +{ + + static final int MAX_SINGLETONS = 64; + private IStub mDownloaderClientStub; + private IDownloaderService mRemoteService; + private TextView mStatusText; + private TextView mProgressFraction; + private TextView mProgressPercent; + private TextView mAverageSpeed; + private TextView mTimeRemaining; + private ProgressBar mPB; + + private View mDashboard; + private View mCellMessage; + + private Button mPauseButton; + private Button mWiFiSettingsButton; + + private boolean use_32_bits=false; + private boolean use_immersive=false; + private boolean mStatePaused; + private int mState; + + 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 ? com.godot.game.R.string.text_button_resume : + com.godot.game.R.string.text_button_pause; + mPauseButton.setText(stringResourceID); + } + + static public class SingletonBase { + + protected void registerClass(String p_name, String[] p_methods) { + + GodotLib.singleton(p_name,this); + + Class clazz = getClass(); + Method[] methods = clazz.getDeclaredMethods(); + for (Method method : methods) { + boolean found=false; + Log.d("XXX","METHOD: %s\n" + method.getName()); + + for (String s : p_methods) { + Log.d("XXX", "METHOD CMP WITH: %s\n" + s); + if (s.equals(method.getName())) { + found=true; + Log.d("XXX","METHOD CMP VALID"); + break; + } + } + if (!found) + continue; + + Log.d("XXX","METHOD FOUND: %s\n" + method.getName()); + + List ptr = new ArrayList(); + + Class[] paramTypes = method.getParameterTypes(); + for (Class c : paramTypes) { + ptr.add(c.getName()); + } + + String[] pt = new String[ptr.size()]; + ptr.toArray(pt); + + GodotLib.method(p_name,method.getName(),method.getReturnType().getName(),pt); + + + } + + Godot.singletons[Godot.singleton_count++]=this; + } + + protected void onMainActivityResult(int requestCode, int resultCode, Intent data) { + + + } + + protected void onMainPause() {} + protected void onMainResume() {} + protected void onMainDestroy() {} + + protected void onGLDrawFrame(GL10 gl) {} + protected void onGLSurfaceChanged(GL10 gl, int width, int height) {} // singletons will always miss first onGLSurfaceChanged call + //protected void onGLSurfaceCreated(GL10 gl, EGLConfig config) {} // singletons won't be ready until first GodotLib.step() + + public void registerMethods() {} + } + +/* + protected List singletons = new ArrayList(); + protected void instanceSingleton(SingletonBase s) { + + s.registerMethods(); + singletons.add(s); + } + +*/ + + private String[] command_line; + + public GodotView mView; + private boolean godot_initialized=false; + + + private SensorManager mSensorManager; + private Sensor mAccelerometer; + + public FrameLayout layout; + public RelativeLayout adLayout; + + + static public GodotIO io; + + public static void setWindowTitle(String title) { + //setTitle(title); + } + + + static SingletonBase singletons[] = new SingletonBase[MAX_SINGLETONS]; + static int singleton_count=0; + + + public interface ResultCallback { + public void callback(int requestCode, int resultCode, Intent data); + }; + public ResultCallback result_callback; + + private PaymentsManager mPaymentsManager = null; + + @Override protected void onActivityResult (int requestCode, int resultCode, Intent data) { + if(requestCode == PaymentsManager.REQUEST_CODE_FOR_PURCHASE){ + mPaymentsManager.processPurchaseResponse(resultCode, data); + }else if (result_callback != null) { + result_callback.callback(requestCode, resultCode, data); + result_callback = null; + }; + + for(int i=0;i65535) { + Log.d("GODOT", "**ERROR** Wrong command len\n"); + return new String[0]; + } + byte[] arg = new byte[strlen]; + r = is.read(arg); + if (r==strlen) { + cmdline[i]=new String(arg,"UTF-8"); + } + } + return cmdline; + } catch (Exception e) { + e.printStackTrace(); + Log.d("GODOT", "**ERROR** Exception " + e.getClass().getName() + ":" + e.getMessage()); + return new String[0]; + } + + + } + + + String expansion_pack_path; + + + private void initializeGodot() { + + if (expansion_pack_path!=null) { + + String[] new_cmdline; + int cll=0; + if (command_line!=null) { + Log.d("GODOT", "initializeGodot: command_line: is not null" ); + new_cmdline = new String[ command_line.length + 2 ]; + cll=command_line.length; + for(int i=0;i new_args = new LinkedList(); + + + for(int i=0;i= 19.0){ // check if the application runs on an android 4.4+ + window.getDecorView().setSystemUiVisibility( + View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar + | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar + | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); + + UiChangeListener(); + } + } else if (command_line[i].equals("-use_apk_expansion")) { + use_apk_expansion=true; + } else if (has_extra && command_line[i].equals("-apk_expansion_md5")) { + main_pack_md5=command_line[i+1]; + i++; + } else if (has_extra && command_line[i].equals("-apk_expansion_key")) { + main_pack_key=command_line[i+1]; + SharedPreferences prefs = getSharedPreferences("app_data_keys", MODE_PRIVATE); + Editor editor = prefs.edit(); + editor.putString("store_public_key", main_pack_key); + + editor.commit(); + i++; + } else if (command_line[i].trim().length()!=0){ + new_args.add(command_line[i]); + } + } + + if (new_args.isEmpty()){ + command_line=null; + }else{ + + command_line = new_args.toArray(new String[new_args.size()]); + } + if (use_apk_expansion && main_pack_md5!=null && main_pack_key!=null) { + //check that environment is ok! + if (!Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED )) { + Log.d("GODOT", "**ERROR! No media mounted!"); + //show popup and die + } + + // Build the full path to the app's expansion files + try { + expansion_pack_path = Environment.getExternalStorageDirectory().toString() + "/Android/obb/"+this.getPackageName(); + expansion_pack_path+="/"+"main."+getPackageManager().getPackageInfo(getPackageName(), 0).versionCode+"."+this.getPackageName()+".obb"; + } catch (Exception e) { + e.printStackTrace(); + } + + File f = new File(expansion_pack_path); + + boolean pack_valid = true; + Log.d("GODOT","**PACK** - Path "+expansion_pack_path); + + if (!f.exists()) { + + pack_valid=false; + Log.d("GODOT","**PACK** - File does not exist"); + + } else if( obbIsCorrupted(expansion_pack_path, main_pack_md5)){ + Log.d("GODOT", "**PACK** - Expansion pack (obb) is corrupted"); + pack_valid = false; + try{ + f.delete(); + }catch(Exception e){ + Log.d("GODOT", "**PACK** - Error deleting corrupted expansion pack (obb)"); + } + } + + if (!pack_valid) { + Log.d("GODOT", "Pack Invalid, try re-downloading."); + + Intent notifierIntent = new Intent(this, this.getClass()); + notifierIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | + Intent.FLAG_ACTIVITY_CLEAR_TOP); + + PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, + notifierIntent, PendingIntent.FLAG_UPDATE_CURRENT); + + int startResult; + try { + Log.d("GODOT", "INITIALIZING DOWNLOAD"); + startResult = DownloaderClientMarshaller.startDownloadServiceIfRequired( + getApplicationContext(), + pendingIntent, + GodotDownloaderService.class); + Log.d("GODOT", "DOWNLOAD SERVICE FINISHED:" + startResult); + + if (startResult != DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED) { + Log.d("GODOT", "DOWNLOAD REQUIRED"); + // This is where you do set up to display the download + // progress (next step) + mDownloaderClientStub = DownloaderClientMarshaller.CreateStub(this, + GodotDownloaderService.class); + + setContentView(com.godot.game.R.layout.downloading_expansion); + mPB = (ProgressBar) findViewById(com.godot.game.R.id.progressBar); + mStatusText = (TextView) findViewById(com.godot.game.R.id.statusText); + mProgressFraction = (TextView) findViewById(com.godot.game.R.id.progressAsFraction); + mProgressPercent = (TextView) findViewById(com.godot.game.R.id.progressAsPercentage); + mAverageSpeed = (TextView) findViewById(com.godot.game.R.id.progressAverageSpeed); + mTimeRemaining = (TextView) findViewById(com.godot.game.R.id.progressTimeRemaining); + mDashboard = findViewById(com.godot.game.R.id.downloaderDashboard); + mCellMessage = findViewById(com.godot.game.R.id.approveCellular); + mPauseButton = (Button) findViewById(com.godot.game.R.id.pauseButton); + mWiFiSettingsButton = (Button) findViewById(com.godot.game.R.id.wifiSettingsButton); + + return; + } else{ + Log.d("GODOT", "NO DOWNLOAD REQUIRED"); + } + } catch (NameNotFoundException e) { + // TODO Auto-generated catch block + Log.d("GODOT", "Error downloading expansion package:" + e.getMessage()); + } + + } + + } + } + + initializeGodot(); + + + // instanceSingleton( new GodotFacebook(this) ); + + + } + + + @Override protected void onDestroy(){ + + if(mPaymentsManager != null ) mPaymentsManager.destroy(); + for(int i=0;i= 19.0){ // check if the application runs on an android 4.4+ + Window window = getWindow(); + window.getDecorView().setSystemUiVisibility( + View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar + | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar + | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); + } + + for(int i=0;i 0) { + complete.update(buffer, 0, numRead); + } + } while (numRead != -1); + + + fis.close(); + byte[] messageDigest = complete.digest(); + + // Create Hex String + StringBuffer hexString = new StringBuffer(); + for (int i=0; i= 0; cnt += cc[i] != 0 ? 1 : 0); + if (cnt == 0) return super.onKeyMultiple(inKeyCode, repeatCount, event); + final Activity me = this; + queueEvent(new Runnable() { + // This method will be called on the rendering thread: + public void run() { + for (int i = 0, n = cc.length; i < n; i++) { + int keyCode; + if ((keyCode = cc[i]) != 0) { + // Simulate key down and up... + GodotLib.key(0, keyCode, true); + GodotLib.key(0, keyCode, false); + } + } + } + }); + return true; + } + + private void queueEvent(Runnable runnable) { + // TODO Auto-generated method stub + + } + + public PaymentsManager getPaymentsManager() { + return mPaymentsManager; + } + +// public void setPaymentsManager(PaymentsManager mPaymentsManager) { +// this.mPaymentsManager = mPaymentsManager; +// }; + + + // Audio + + /** + * 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) { + Log.d("GODOT", "onDownloadStateChanged:" + newState); + setState(newState); + boolean showDashboard = true; + boolean showCellMessage = false; + boolean paused; + boolean indeterminate; + switch (newState) { + case IDownloaderClient.STATE_IDLE: + Log.d("GODOT", "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: + Log.d("GODOT", "STATE CONNECTION / FETCHING URL"); + showDashboard = true; + paused = false; + indeterminate = true; + break; + case IDownloaderClient.STATE_DOWNLOADING: + Log.d("GODOT", "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: + Log.d("GODOT", "MANY TYPES OF FAILING"); + paused = true; + showDashboard = false; + indeterminate = false; + break; + case IDownloaderClient.STATE_PAUSED_NEED_CELLULAR_PERMISSION: + case IDownloaderClient.STATE_PAUSED_WIFI_DISABLED_NEED_CELLULAR_PERMISSION: + Log.d("GODOT", "PAUSED FOR SOME STUPID REASON"); + showDashboard = false; + paused = true; + indeterminate = false; + showCellMessage = true; + break; + + case IDownloaderClient.STATE_PAUSED_BY_REQUEST: + Log.d("GODOT", "PAUSED BY STUPID USER"); + paused = true; + indeterminate = false; + break; + case IDownloaderClient.STATE_PAUSED_ROAMING: + case IDownloaderClient.STATE_PAUSED_SDCARD_UNAVAILABLE: + Log.d("GODOT", "PAUSED BY ROAMING WTF!?"); + paused = true; + indeterminate = false; + break; + case IDownloaderClient.STATE_COMPLETED: + Log.d("GODOT", "COMPLETED"); + showDashboard = false; + paused = false; + indeterminate = false; +// validateXAPKZipFiles(); + initializeGodot(); + return; + default: + Log.d("GODOT", "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); + } + + + @Override + public void onDownloadProgress(DownloadProgressInfo progress) { + mAverageSpeed.setText(getString(com.godot.game.R.string.kilobytes_per_second, + Helpers.getSpeedString(progress.mCurrentSpeed))); + mTimeRemaining.setText(getString(com.godot.game.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)); + + } + +} -- cgit v1.2.3-70-g09d2