1 // This string is autogenerated by ChangeAppSettings.sh, do not change spaces amount 2 package org.warmux; 3 4 import android.app.Activity; 5 import android.content.Context; 6 import android.os.Bundle; 7 import android.view.MotionEvent; 8 import android.view.KeyEvent; 9 import android.view.Window; 10 import android.view.WindowManager; 11 import android.view.View; 12 import android.view.ViewGroup; 13 import android.widget.TextView; 14 import android.widget.EditText; 15 import android.text.Editable; 16 import android.widget.Button; 17 import android.widget.ImageView; 18 import android.widget.LinearLayout; 19 import android.widget.FrameLayout; 20 import android.content.res.Configuration; 21 import android.app.Notification; 22 import android.app.NotificationManager; 23 import android.app.PendingIntent; 24 import android.content.Intent; 25 import android.view.View.OnKeyListener; 26 import android.text.method.TextKeyListener; 27 import java.util.LinkedList; 28 import java.io.SequenceInputStream; 29 import java.io.BufferedInputStream; 30 import java.io.IOException; 31 import java.io.InputStream; 32 import java.io.OutputStream; 33 import java.io.FileOutputStream; 34 import java.io.File; 35 import java.util.zip.ZipEntry; 36 import java.util.zip.ZipInputStream; 37 import android.text.SpannedString; 38 39 40 public class MainActivity extends Activity { 41 @Override onCreate(Bundle savedInstanceState)42 protected void onCreate(Bundle savedInstanceState) { 43 super.onCreate(savedInstanceState); 44 45 // fullscreen mode 46 requestWindowFeature(Window.FEATURE_NO_TITLE); 47 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 48 WindowManager.LayoutParams.FLAG_FULLSCREEN); 49 if(Globals.InhibitSuspend) 50 getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, 51 WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 52 53 System.out.println("libSDL: Creating startup screen"); 54 _layout = new LinearLayout(this); 55 _layout.setOrientation(LinearLayout.VERTICAL); 56 _layout.setLayoutParams(new LinearLayout.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT)); 57 _layout2 = new LinearLayout(this); 58 _layout2.setLayoutParams(new LinearLayout.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); 59 60 _btn = new Button(this); 61 _btn.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); 62 _btn.setText(getResources().getString(R.string.device_change_cfg)); 63 class onClickListener implements View.OnClickListener 64 { 65 public MainActivity p; 66 onClickListener( MainActivity _p ) { p = _p; } 67 public void onClick(View v) 68 { 69 setUpStatusLabel(); 70 System.out.println("libSDL: User clicked change phone config button"); 71 Settings.showConfig(p); 72 } 73 }; 74 _btn.setOnClickListener(new onClickListener(this)); 75 76 _layout2.addView(_btn); 77 78 _layout.addView(_layout2); 79 80 ImageView img = new ImageView(this); 81 82 img.setScaleType(ImageView.ScaleType.FIT_CENTER /* FIT_XY */ ); 83 img.setImageResource(R.drawable.publisherlogo); 84 img.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT)); 85 _layout.addView(img); 86 87 _videoLayout = new FrameLayout(this); 88 _videoLayout.addView(_layout); 89 90 setContentView(_videoLayout); 91 92 if(mAudioThread == null) // Starting from background (should not happen) 93 { 94 System.out.println("libSDL: Loading libraries"); 95 LoadLibraries(); 96 mAudioThread = new AudioThread(this); 97 System.out.println("libSDL: Loading settings"); 98 Settings.Load(this); 99 } 100 101 if( !Settings.settingsChanged ) 102 { 103 System.out.println("libSDL: 3-second timeout in startup screen"); 104 class Callback implements Runnable 105 { 106 MainActivity p; 107 Callback( MainActivity _p ) { p = _p; } 108 public void run() 109 { 110 try { 111 Thread.sleep(3000); 112 } catch( InterruptedException e ) {}; 113 if( Settings.settingsChanged ) 114 return; 115 System.out.println("libSDL: Timeout reached in startup screen, process with downloader"); 116 p.startDownloader(); 117 } 118 }; 119 Thread changeConfigAlertThread = null; 120 changeConfigAlertThread = new Thread(new Callback(this)); 121 changeConfigAlertThread.start(); 122 } 123 } 124 setUpStatusLabel()125 public void setUpStatusLabel() 126 { 127 MainActivity Parent = this; // Too lazy to rename 128 if( Parent._btn != null ) 129 { 130 Parent._layout2.removeView(Parent._btn); 131 Parent._btn = null; 132 } 133 if( Parent._tv == null ) 134 { 135 Parent._tv = new TextView(Parent); 136 Parent._tv.setMaxLines(1); 137 Parent._tv.setText(R.string.init); 138 Parent._layout2.addView(Parent._tv); 139 } 140 } 141 startDownloader()142 public void startDownloader() 143 { 144 System.out.println("libSDL: Starting data downloader"); 145 class Callback implements Runnable 146 { 147 public MainActivity Parent; 148 public void run() 149 { 150 setUpStatusLabel(); 151 System.out.println("libSDL: Starting downloader"); 152 if( Parent.downloader == null ) 153 Parent.downloader = new DataDownloader(Parent, Parent._tv); 154 } 155 } 156 Callback cb = new Callback(); 157 cb.Parent = this; 158 this.runOnUiThread(cb); 159 } 160 initSDL()161 public void initSDL() 162 { 163 if(sdlInited) 164 return; 165 System.out.println("libSDL: Initializing video and SDL application"); 166 sdlInited = true; 167 if(Globals.UseAccelerometerAsArrowKeys) 168 getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, 169 WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 170 _videoLayout.removeView(_layout); 171 _layout = null; 172 _layout2 = null; 173 _btn = null; 174 _tv = null; 175 _videoLayout = new FrameLayout(this); 176 setContentView(_videoLayout); 177 mGLView = new DemoGLSurfaceView(this); 178 _videoLayout.addView(mGLView); 179 // Receive keyboard events 180 mGLView.setFocusableInTouchMode(true); 181 mGLView.setFocusable(true); 182 mGLView.requestFocus(); 183 } 184 185 @Override onPause()186 protected void onPause() { 187 if( downloader != null ) { 188 synchronized( downloader ) { 189 downloader.setStatusField(null); 190 } 191 } 192 _isPaused = true; 193 if( mGLView != null ) 194 mGLView.onPause(); 195 super.onPause(); 196 } 197 198 @Override onResume()199 protected void onResume() { 200 super.onResume(); 201 if( mGLView != null ) 202 mGLView.onResume(); 203 else 204 if( downloader != null ) { 205 synchronized( downloader ) { 206 downloader.setStatusField(_tv); 207 if( downloader.DownloadComplete ) 208 initSDL(); 209 } 210 } 211 _isPaused = false; 212 } 213 isPaused()214 public boolean isPaused() 215 { 216 return _isPaused; 217 } 218 219 @Override onDestroy()220 protected void onDestroy() 221 { 222 if( downloader != null ) { 223 synchronized( downloader ) { 224 downloader.setStatusField(null); 225 } 226 } 227 if( mGLView != null ) 228 mGLView.exitApp(); 229 super.onDestroy(); 230 System.exit(0); 231 } 232 hideScreenKeyboard()233 public void hideScreenKeyboard() 234 { 235 if(_screenKeyboard == null) 236 return; 237 238 synchronized(textInput) 239 { 240 String text = _screenKeyboard.getText().toString(); 241 for(int i = 0; i < text.length(); i++) 242 { 243 DemoRenderer.nativeTextInput( (int)text.charAt(i), (int)text.codePointAt(i) ); 244 } 245 } 246 DemoRenderer.nativeTextInputFinished(); 247 _videoLayout.removeView(_screenKeyboard); 248 _screenKeyboard = null; 249 mGLView.setFocusableInTouchMode(true); 250 mGLView.setFocusable(true); 251 mGLView.requestFocus(); 252 }; 253 showScreenKeyboard(final String oldText, boolean sendBackspace)254 public void showScreenKeyboard(final String oldText, boolean sendBackspace) 255 { 256 if(_screenKeyboard != null) 257 return; 258 class myKeyListener implements OnKeyListener 259 { 260 MainActivity _parent; 261 boolean sendBackspace; 262 myKeyListener(MainActivity parent, boolean sendBackspace) { _parent = parent; this.sendBackspace = sendBackspace; }; 263 public boolean onKey(View v, int keyCode, KeyEvent event) 264 { 265 if ((event.getAction() == KeyEvent.ACTION_UP) && ((keyCode == KeyEvent.KEYCODE_ENTER) || (keyCode == KeyEvent.KEYCODE_BACK))) 266 { 267 _parent.hideScreenKeyboard(); 268 return true; 269 } 270 if ((sendBackspace && event.getAction() == KeyEvent.ACTION_UP) && (keyCode == KeyEvent.KEYCODE_DEL || keyCode == KeyEvent.KEYCODE_CLEAR)) 271 { 272 synchronized(textInput) { 273 DemoRenderer.nativeTextInput( 8, 0 ); // Send backspace to native code 274 } 275 return false; // and proceed to delete text in keyboard input field 276 } 277 return false; 278 } 279 }; 280 _screenKeyboard = new EditText(this); 281 _videoLayout.addView(_screenKeyboard); 282 _screenKeyboard.setOnKeyListener(new myKeyListener(this, sendBackspace)); 283 _screenKeyboard.setHint(R.string.text_edit_click_here); 284 _screenKeyboard.setText(oldText); 285 final Window window = getWindow(); 286 _screenKeyboard.setOnFocusChangeListener(new View.OnFocusChangeListener() { 287 public void onFocusChange(View v, boolean hasFocus) 288 { 289 if (hasFocus) 290 window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); 291 } 292 }); 293 _screenKeyboard.setKeyListener(new TextKeyListener(TextKeyListener.Capitalize.NONE, false)); 294 _screenKeyboard.setFocusableInTouchMode(true); 295 _screenKeyboard.setFocusable(true); 296 _screenKeyboard.requestFocus(); 297 }; 298 299 @Override onKeyDown(int keyCode, final KeyEvent event)300 public boolean onKeyDown(int keyCode, final KeyEvent event) { 301 // Overrides Back key to use in our app 302 if(_screenKeyboard != null) 303 _screenKeyboard.onKeyDown(keyCode, event); 304 else 305 if( mGLView != null ) 306 mGLView.nativeKey( keyCode, 1 ); 307 else 308 if( keyCode == KeyEvent.KEYCODE_BACK && downloader != null ) 309 { 310 if( downloader.DownloadFailed ) 311 System.exit(1); 312 if( !downloader.DownloadComplete ) 313 onStop(); 314 } 315 else 316 if( keyListener != null ) 317 { 318 keyListener.onKeyEvent(keyCode); 319 } 320 return true; 321 } 322 323 @Override onKeyUp(int keyCode, final KeyEvent event)324 public boolean onKeyUp(int keyCode, final KeyEvent event) { 325 if(_screenKeyboard != null) 326 _screenKeyboard.onKeyUp(keyCode, event); 327 else 328 if( mGLView != null ) 329 mGLView.nativeKey( keyCode, 0 ); 330 return true; 331 } 332 333 @Override dispatchTouchEvent(final MotionEvent ev)334 public boolean dispatchTouchEvent(final MotionEvent ev) { 335 if(_screenKeyboard != null) 336 _screenKeyboard.dispatchTouchEvent(ev); 337 else 338 if(mGLView != null) 339 mGLView.onTouchEvent(ev); 340 else 341 if( _btn != null ) 342 return _btn.dispatchTouchEvent(ev); 343 else 344 if( touchListener != null ) 345 touchListener.onTouchEvent(ev); 346 return true; 347 } 348 349 @Override onConfigurationChanged(Configuration newConfig)350 public void onConfigurationChanged(Configuration newConfig) { 351 super.onConfigurationChanged(newConfig); 352 // Do nothing here 353 } 354 setText(final String t)355 public void setText(final String t) 356 { 357 class Callback implements Runnable 358 { 359 MainActivity Parent; 360 public SpannedString text; 361 public void run() 362 { 363 Parent.setUpStatusLabel(); 364 if(Parent._tv != null) 365 Parent._tv.setText(text); 366 } 367 } 368 Callback cb = new Callback(); 369 cb.text = new SpannedString(t); 370 cb.Parent = this; 371 this.runOnUiThread(cb); 372 } 373 showTaskbarNotification()374 public void showTaskbarNotification() 375 { 376 showTaskbarNotification("SDL application paused", "SDL application", "Application is paused, click to activate"); 377 } 378 379 // Stolen from SDL port by Mamaich showTaskbarNotification(String text0, String text1, String text2)380 public void showTaskbarNotification(String text0, String text1, String text2) 381 { 382 NotificationManager NotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 383 Intent intent = new Intent(this, MainActivity.class); 384 PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK); 385 Notification n = new Notification(R.drawable.icon, text0, System.currentTimeMillis()); 386 n.setLatestEventInfo(this, text1, text2, pendingIntent); 387 NotificationManager.notify(NOTIFY_ID, n); 388 } 389 hideTaskbarNotification()390 public void hideTaskbarNotification() 391 { 392 NotificationManager NotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 393 NotificationManager.cancel(NOTIFY_ID); 394 } 395 LoadLibraries()396 public void LoadLibraries() 397 { 398 try 399 { 400 for(String l : Globals.AppLibraries) 401 { 402 try 403 { 404 String libname = System.mapLibraryName(l); 405 File libpath = new File(getFilesDir().getAbsolutePath() + "/../lib/" + libname); 406 System.out.println("libSDL: loading lib " + libpath.getAbsolutePath()); 407 System.load(libpath.getPath()); 408 } 409 catch( UnsatisfiedLinkError e ) 410 { 411 System.loadLibrary(l); 412 } 413 } 414 } 415 catch ( UnsatisfiedLinkError e ) 416 { 417 try { 418 System.out.println("libSDL: Extracting APP2SD-ed libs"); 419 420 InputStream in = null; 421 try 422 { 423 for( int i = 0; ; i++ ) 424 { 425 InputStream in2 = getAssets().open("bindata" + String.valueOf(i)); 426 if( in == null ) 427 in = in2; 428 else 429 in = new SequenceInputStream( in, in2 ); 430 } 431 } 432 catch( IOException ee ) { } 433 434 if( in == null ) 435 throw new RuntimeException("libSDL: Extracting APP2SD-ed libs failed, the .apk file packaged incorrectly"); 436 437 ZipInputStream zip = new ZipInputStream(in); 438 439 File cacheDir = getCacheDir(); 440 try { 441 cacheDir.mkdirs(); 442 } catch( SecurityException ee ) { }; 443 444 byte[] buf = new byte[16384]; 445 while(true) 446 { 447 ZipEntry entry = null; 448 entry = zip.getNextEntry(); 449 /* 450 if( entry != null ) 451 System.out.println("Extracting lib " + entry.getName()); 452 */ 453 if( entry == null ) 454 { 455 System.out.println("Extracting libs finished"); 456 break; 457 } 458 if( entry.isDirectory() ) 459 { 460 System.out.println("Warning '" + entry.getName() + "' is a directory"); 461 continue; 462 } 463 464 OutputStream out = null; 465 String path = cacheDir.getAbsolutePath() + "/" + entry.getName(); 466 467 System.out.println("Saving to file '" + path + "'"); 468 469 out = new FileOutputStream( path ); 470 int len = zip.read(buf); 471 while (len >= 0) 472 { 473 if(len > 0) 474 out.write(buf, 0, len); 475 len = zip.read(buf); 476 } 477 478 out.flush(); 479 out.close(); 480 } 481 482 for(String l : Globals.AppLibraries) 483 { 484 String libname = System.mapLibraryName(l); 485 File libpath = new File(cacheDir, libname); 486 System.out.println("libSDL: loading lib " + libpath.getPath()); 487 System.load(libpath.getPath()); 488 libpath.delete(); 489 } 490 } 491 catch ( Exception ee ) 492 { 493 System.out.println("libSDL: Error: " + e.toString()); 494 } 495 } 496 }; 497 getVideoLayout()498 public FrameLayout getVideoLayout() { return _videoLayout; } 499 500 static int NOTIFY_ID = 12367098; // Random ID 501 502 private static DemoGLSurfaceView mGLView = null; 503 private static AudioThread mAudioThread = null; 504 private static DataDownloader downloader = null; 505 506 private TextView _tv = null; 507 private Button _btn = null; 508 private LinearLayout _layout = null; 509 private LinearLayout _layout2 = null; 510 511 private FrameLayout _videoLayout = null; 512 private EditText _screenKeyboard = null; 513 private boolean sdlInited = false; 514 public Settings.TouchEventsListener touchListener = null; 515 public Settings.KeyEventsListener keyListener = null; 516 boolean _isPaused = false; 517 518 public LinkedList<Integer> textInput = new LinkedList<Integer> (); 519 520 } 521