OSDN Git Service

getLogLevel() in Application interface
[mikumikustudio/libgdx-mikumikustudio.git] / backends / gdx-backend-android / src / com / badlogic / gdx / backends / android / AndroidDaydream.java
1 /*******************************************************************************
2  * Copyright 2011 See AUTHORS file.
3  * 
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  * 
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  * 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  ******************************************************************************/
16
17 package com.badlogic.gdx.backends.android;
18
19 import java.lang.reflect.Method;
20
21 import android.app.Activity;
22 import android.content.Context;
23 import android.content.res.Configuration;
24 import android.os.Bundle;
25 import android.os.Debug;
26 import android.os.Handler;
27 import android.os.PowerManager;
28 import android.os.PowerManager.WakeLock;
29 import android.service.dreams.DreamService;
30 import android.util.Log;
31 import android.view.Gravity;
32 import android.view.View;
33 import android.widget.FrameLayout;
34
35 import com.badlogic.gdx.Application;
36 import com.badlogic.gdx.ApplicationListener;
37 import com.badlogic.gdx.Audio;
38 import com.badlogic.gdx.Files;
39 import com.badlogic.gdx.Gdx;
40 import com.badlogic.gdx.Graphics;
41 import com.badlogic.gdx.Input;
42 import com.badlogic.gdx.LifecycleListener;
43 import com.badlogic.gdx.Net;
44 import com.badlogic.gdx.Preferences;
45 import com.badlogic.gdx.backends.android.surfaceview.FillResolutionStrategy;
46 import com.badlogic.gdx.backends.android.surfaceview.GLSurfaceViewCupcake;
47 import com.badlogic.gdx.graphics.GL10;
48 import com.badlogic.gdx.graphics.GL11;
49 import com.badlogic.gdx.utils.Array;
50 import com.badlogic.gdx.utils.Clipboard;
51 import com.badlogic.gdx.utils.GdxNativesLoader;
52
53 /** An implementation of the {@link Application} interface for Android. Create an {@link Activity} that derives from this class. In
54  * the Activity#onCreate(Bundle) method call the {@link #initialize(ApplicationListener, boolean)} method specifying the
55  * configuration for the GLSurfaceView.
56  * 
57  * @author mzechner */
58 public class AndroidDaydream extends DreamService implements Application {
59         static {
60                 GdxNativesLoader.load();
61         }
62
63         protected AndroidGraphicsDaydream graphics;
64         protected AndroidInput input;
65         protected AndroidAudio audio;
66         protected AndroidFiles files;
67         protected AndroidNet net;
68         protected ApplicationListener listener;
69         protected Handler handler;
70         protected boolean firstResume = true;
71         protected final Array<Runnable> runnables = new Array<Runnable>();
72         protected final Array<Runnable> executedRunnables = new Array<Runnable>();
73         protected final Array<LifecycleListener> lifecycleListeners = new Array<LifecycleListener>();
74         protected WakeLock wakeLock = null;
75         protected int logLevel = LOG_INFO;
76
77         /** This method has to be called in the Activity#onCreate(Bundle) method. It sets up all the things necessary to get input,
78          * render via OpenGL and so on. If useGL20IfAvailable is set the AndroidApplication will try to create an OpenGL ES 2.0 context
79          * which can then be used via {@link Graphics#getGL20()}. The {@link GL10} and {@link GL11} interfaces should not be used when
80          * OpenGL ES 2.0 is enabled. To query whether enabling OpenGL ES 2.0 was successful use the {@link Graphics#isGL20Available()}
81          * method. Uses a default {@link AndroidApplicationConfiguration}.
82          * 
83          * @param listener the {@link ApplicationListener} implementing the program logic
84          * @param useGL2IfAvailable whether to use OpenGL ES 2.0 if its available. */
85         public void initialize (ApplicationListener listener, boolean useGL2IfAvailable) {
86                 AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
87                 config.useGL20 = useGL2IfAvailable;
88                 initialize(listener, config);
89         }
90
91         /** This method has to be called in the Activity#onCreate(Bundle) method. It sets up all the things necessary to get input,
92          * render via OpenGL and so on. If config.useGL20 is set the AndroidApplication will try to create an OpenGL ES 2.0 context
93          * which can then be used via {@link Graphics#getGL20()}. The {@link GL10} and {@link GL11} interfaces should not be used when
94          * OpenGL ES 2.0 is enabled. To query whether enabling OpenGL ES 2.0 was successful use the {@link Graphics#isGL20Available()}
95          * method. You can configure other aspects of the application with the rest of the fields in the
96          * {@link AndroidApplicationConfiguration} instance.
97          * 
98          * @param listener the {@link ApplicationListener} implementing the program logic
99          * @param config the {@link AndroidApplicationConfiguration}, defining various settings of the application (use accelerometer,
100          *           etc.). */
101         public void initialize (ApplicationListener listener, AndroidApplicationConfiguration config) {
102                 graphics = new AndroidGraphicsDaydream(this, config, config.resolutionStrategy == null ? new FillResolutionStrategy()
103                         : config.resolutionStrategy);
104                 input = AndroidInputFactory.newAndroidInput(this, this, graphics.view, config);
105                 audio = new AndroidAudio(this, config);
106                 files = new AndroidFiles(this.getAssets(), this.getFilesDir().getAbsolutePath());
107                 net = new AndroidNet(null);
108                 this.listener = listener;
109                 this.handler = new Handler();
110
111                 Gdx.app = this;
112                 Gdx.input = this.getInput();
113                 Gdx.audio = this.getAudio();
114                 Gdx.files = this.getFiles();
115                 Gdx.graphics = this.getGraphics();
116                 Gdx.net = this.getNet();
117
118                 setFullscreen(true);
119
120                 setContentView(graphics.getView(), createLayoutParams());
121                 createWakeLock(config);
122                 hideStatusBar(config);
123         }
124
125         protected FrameLayout.LayoutParams createLayoutParams () {
126                 FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(android.view.ViewGroup.LayoutParams.FILL_PARENT,
127                         android.view.ViewGroup.LayoutParams.FILL_PARENT);
128                 layoutParams.gravity = Gravity.CENTER;
129                 return layoutParams;
130         }
131
132         protected void createWakeLock (AndroidApplicationConfiguration config) {
133                 if (config.useWakelock) {
134                         PowerManager powerManager = (PowerManager)getSystemService(Context.POWER_SERVICE);
135                         wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "libgdx wakelock");
136                 }
137         }
138
139         protected void hideStatusBar (AndroidApplicationConfiguration config) {
140                 if (!config.hideStatusBar || getVersion() < 11) return;
141
142                 View rootView = getWindow().getDecorView();
143
144                 try {
145                         Method m = View.class.getMethod("setSystemUiVisibility", int.class);
146                         m.invoke(rootView, 0x0);
147                         m.invoke(rootView, 0x1);
148                 } catch (Exception e) {
149                         log("AndroidApplication", "Can't hide status bar", e);
150                 }
151         }
152
153         /** This method has to be called in the Activity#onCreate(Bundle) method. It sets up all the things necessary to get input,
154          * render via OpenGL and so on. If useGL20IfAvailable is set the AndroidApplication will try to create an OpenGL ES 2.0 context
155          * which can then be used via {@link Graphics#getGL20()}. The {@link GL10} and {@link GL11} interfaces should not be used when
156          * OpenGL ES 2.0 is enabled. To query whether enabling OpenGL ES 2.0 was successful use the {@link Graphics#isGL20Available()}
157          * method. Uses a default {@link AndroidApplicationConfiguration}.
158          * <p/>
159          * Note: you have to add the returned view to your layout!
160          * 
161          * @param listener the {@link ApplicationListener} implementing the program logic
162          * @param useGL2IfAvailable whether to use OpenGL ES 2.0 if its available.
163          * @return the GLSurfaceView of the application */
164         public View initializeForView (ApplicationListener listener, boolean useGL2IfAvailable) {
165                 AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
166                 config.useGL20 = useGL2IfAvailable;
167                 return initializeForView(listener, config);
168         }
169
170         /** This method has to be called in the Activity#onCreate(Bundle) method. It sets up all the things necessary to get input,
171          * render via OpenGL and so on. If config.useGL20 is set the AndroidApplication will try to create an OpenGL ES 2.0 context
172          * which can then be used via {@link Graphics#getGL20()}. The {@link GL10} and {@link GL11} interfaces should not be used when
173          * OpenGL ES 2.0 is enabled. To query whether enabling OpenGL ES 2.0 was successful use the {@link Graphics#isGL20Available()}
174          * method. You can configure other aspects of the application with the rest of the fields in the
175          * {@link AndroidApplicationConfiguration} instance.
176          * <p/>
177          * Note: you have to add the returned view to your layout!
178          * 
179          * @param listener the {@link ApplicationListener} implementing the program logic
180          * @param config the {@link AndroidApplicationConfiguration}, defining various settings of the application (use accelerometer,
181          *           etc.).
182          * @return the GLSurfaceView of the application */
183         public View initializeForView (ApplicationListener listener, AndroidApplicationConfiguration config) {
184                 graphics = new AndroidGraphicsDaydream(this, config, config.resolutionStrategy == null ? new FillResolutionStrategy()
185                         : config.resolutionStrategy);
186                 input = AndroidInputFactory.newAndroidInput(this, this, graphics.view, config);
187                 audio = new AndroidAudio(this, config);
188                 files = new AndroidFiles(this.getAssets(), this.getFilesDir().getAbsolutePath());
189                 net = new AndroidNet(null);
190                 this.listener = listener;
191                 this.handler = new Handler();
192
193                 Gdx.app = this;
194                 Gdx.input = this.getInput();
195                 Gdx.audio = this.getAudio();
196                 Gdx.files = this.getFiles();
197                 Gdx.graphics = this.getGraphics();
198                 Gdx.net = this.getNet();
199
200                 createWakeLock(config);
201                 hideStatusBar(config);
202                 return graphics.getView();
203         }
204
205         @Override
206         public void onDreamingStopped () {
207                 if (wakeLock != null) wakeLock.release();
208                 boolean isContinuous = graphics.isContinuousRendering();
209                 graphics.setContinuousRendering(true);
210                 graphics.pause();
211
212                 input.unregisterSensorListeners();
213                 // erase pointer ids. this sucks donkeyballs...
214                 int[] realId = input.realId;
215                 for (int i = 0; i < realId.length; i++)
216                         realId[i] = -1;
217                 // erase touched state. this also sucks donkeyballs...
218                 boolean[] touched = input.touched;
219                 for (int i = 0; i < touched.length; i++)
220                         touched[i] = false;
221
222                 graphics.clearManagedCaches();
223                 graphics.destroy();
224                 graphics.setContinuousRendering(isContinuous);
225
226                 if (graphics != null && graphics.view != null) {
227                         if (graphics.view instanceof GLSurfaceViewCupcake) ((GLSurfaceViewCupcake)graphics.view).onPause();
228                         if (graphics.view instanceof android.opengl.GLSurfaceView) ((android.opengl.GLSurfaceView)graphics.view).onPause();
229                 }
230
231                 super.onDreamingStopped();
232         }
233
234         @Override
235         public void onDreamingStarted () {
236                 if (wakeLock != null) wakeLock.acquire();
237                 Gdx.app = this;
238                 Gdx.input = this.getInput();
239                 Gdx.audio = this.getAudio();
240                 Gdx.files = this.getFiles();
241                 Gdx.graphics = this.getGraphics();
242                 Gdx.net = this.getNet();
243
244                 ((AndroidInput)getInput()).registerSensorListeners();
245
246                 if (graphics != null && graphics.view != null) {
247                         if (graphics.view instanceof GLSurfaceViewCupcake) ((GLSurfaceViewCupcake)graphics.view).onResume();
248                         if (graphics.view instanceof android.opengl.GLSurfaceView) ((android.opengl.GLSurfaceView)graphics.view).onResume();
249                 }
250
251                 if (!firstResume) {
252                         graphics.resume();
253                 } else
254                         firstResume = false;
255                 super.onDreamingStarted();
256         }
257
258         @Override
259         public void onDetachedFromWindow () {
260                 super.onDetachedFromWindow();
261         }
262
263         @Override
264         public ApplicationListener getApplicationListener () {
265                 return listener;
266         }
267
268         @Override
269         public Audio getAudio () {
270                 return audio;
271         }
272
273         @Override
274         public Files getFiles () {
275                 return files;
276         }
277
278         @Override
279         public Graphics getGraphics () {
280                 return graphics;
281         }
282
283         @Override
284         public Input getInput () {
285                 return input;
286         }
287
288         @Override
289         public Net getNet () {
290                 return net;
291         }
292
293         @Override
294         public ApplicationType getType () {
295                 return ApplicationType.Android;
296         }
297
298         @Override
299         public int getVersion () {
300                 return Integer.parseInt(android.os.Build.VERSION.SDK);
301         }
302
303         @Override
304         public long getJavaHeap () {
305                 return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
306         }
307
308         @Override
309         public long getNativeHeap () {
310                 return Debug.getNativeHeapAllocatedSize();
311         }
312
313         @Override
314         public Preferences getPreferences (String name) {
315                 return new AndroidPreferences(getSharedPreferences(name, Context.MODE_PRIVATE));
316         }
317
318         AndroidClipboard clipboard;
319
320         @Override
321         public Clipboard getClipboard () {
322                 if (clipboard == null) {
323                         clipboard = new AndroidClipboard(this);
324                 }
325                 return clipboard;
326         }
327
328         @Override
329         public void postRunnable (Runnable runnable) {
330                 synchronized (runnables) {
331                         runnables.add(runnable);
332                         Gdx.graphics.requestRendering();
333                 }
334         }
335
336         @Override
337         public void onConfigurationChanged (Configuration config) {
338                 super.onConfigurationChanged(config);
339                 boolean keyboardAvailable = false;
340                 if (config.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) keyboardAvailable = true;
341                 input.keyboardAvailable = keyboardAvailable;
342         }
343
344         @Override
345         public void exit () {
346                 handler.post(new Runnable() {
347                         @Override
348                         public void run () {
349                                 AndroidDaydream.this.finish();
350                         }
351                 });
352         }
353
354         @Override
355         public void debug (String tag, String message) {
356                 if (logLevel >= LOG_DEBUG) {
357                         Log.d(tag, message);
358                 }
359         }
360
361         @Override
362         public void debug (String tag, String message, Throwable exception) {
363                 if (logLevel >= LOG_DEBUG) {
364                         Log.d(tag, message, exception);
365                 }
366         }
367
368         @Override
369         public void log (String tag, String message) {
370                 if (logLevel >= LOG_INFO) Log.i(tag, message);
371         }
372
373         @Override
374         public void log (String tag, String message, Exception exception) {
375                 if (logLevel >= LOG_INFO) Log.i(tag, message, exception);
376         }
377
378         @Override
379         public void error (String tag, String message) {
380                 if (logLevel >= LOG_ERROR) Log.e(tag, message);
381         }
382
383         @Override
384         public void error (String tag, String message, Throwable exception) {
385                 if (logLevel >= LOG_ERROR) Log.e(tag, message, exception);
386         }
387
388         @Override
389         public void setLogLevel (int logLevel) {
390                 this.logLevel = logLevel;
391         }
392
393         @Override
394         public int getLogLevel() {
395                 return logLevel;
396         }
397
398         @Override
399         public void addLifecycleListener (LifecycleListener listener) {
400                 synchronized (lifecycleListeners) {
401                         lifecycleListeners.add(listener);
402                 }
403         }
404
405         @Override
406         public void removeLifecycleListener (LifecycleListener listener) {
407                 synchronized (lifecycleListeners) {
408                         lifecycleListeners.removeValue(listener, true);
409                 }
410         }
411 }