// -*- mode: java; c-basic-offset: 2; -*- // Copyright 2009-2011 Google, All Rights reserved // Copyright 2011-2012 MIT, All rights reserved // Released under the Apache License, Version 2.0 // http://www.apache.org/licenses/LICENSE-2.0 package com.google.appinventor.components.runtime.util; import android.app.Activity; import android.content.Context; import android.media.AudioManager; import android.net.http.SslError; import android.view.Display; import android.webkit.SslErrorHandler; import android.webkit.WebView; import android.webkit.WebViewClient; import com.google.appinventor.components.runtime.Component; import com.google.appinventor.components.runtime.Form; import com.google.appinventor.components.runtime.Player; /** * Helper methods for calling methods added in Froyo (2.2, API level 8). * */ public class FroyoUtil { private FroyoUtil() { } /** * Calls {@link Display#getRotation()} * * @return one of {@link android.view.Surface#ROTATION_0}, * {@link android.view.Surface#ROTATION_90}, * {@link android.view.Surface#ROTATION_180}, * or {@link android.view.Surface#ROTATION_180}. */ public static int getRotation(Display display) { return display.getRotation(); } // Methods for Player Component /** * Utility method that returns and AudioManager for the Activity passed in * @param activity the Activity that will be associated to the AudioManager * @return the AudioManager object for the passed Activity */ public static AudioManager setAudioManager(Activity activity) { return (AudioManager) activity.getSystemService(Context.AUDIO_SERVICE); } /** * Utility method to generate a listener for changed on Focus. Only available in API Level 8 * @param player the player which focus will be watched for * @return a listener object with associated callbacks for each state. */ public static Object setAudioFocusChangeListener(final Player player) { Object afChangeListener = (android.media.AudioManager.OnAudioFocusChangeListener) new android .media.AudioManager.OnAudioFocusChangeListener() { private boolean playbackFlag = false; /** * This callback method is triggered when audio focus changes. This is necessary because * several apps can be managing audio at the same time and for them to interact correctly, * they should be using an AudioManager: http://developer.android.com/training/managing-audio/audio-focus.html * @param focusChange the type of focus change */ @Override public void onAudioFocusChange(int focusChange) { switch(focusChange){ case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: // Focus loss transient: Pause playback if (player != null && player.playerState == Player.State.PLAYING) { player.pause(); playbackFlag = true; } break; case AudioManager.AUDIOFOCUS_LOSS: // Focus loss permanent: focus taken by other players playbackFlag = false; player.OtherPlayerStarted(); break; case AudioManager.AUDIOFOCUS_GAIN: // Focus gain: Resume playback if (player != null && playbackFlag && player.playerState == Player.State.PAUSED_BY_EVENT) { player.Start(); playbackFlag = false; } break; } } }; return afChangeListener; } /** * Utility method that * @param am the AudioManager requesting the focus * @param afChangeListener the foucs listener associated to the AudioManager * @return true if focus is granted, false if not. */ public static boolean focusRequestGranted(AudioManager am, Object afChangeListener) { int result = am.requestAudioFocus((AudioManager.OnAudioFocusChangeListener) afChangeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN); return result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED; } /** * Utility method to abandon audio focus given an AudioManager object * @param am the AudioManager object * @param afChangeListener the foucs listener associated to the AudioManager */ public static void abandonFocus(AudioManager am, Object afChangeListener) { am.abandonAudioFocus((AudioManager.OnAudioFocusChangeListener) afChangeListener); } /** * Get a special WebViewClient that handles SslError. This is used so the * App Inventor programmer can permit https connections to sites with self * signed certificates. It represents a security risk because a Man in the * Middle (MITM) attack will not be detected if we ignore SslErrors. * * @param ignoreErrors set to true to ignore errors */ public static WebViewClient getWebViewClient(final boolean ignoreErrors, final boolean followLinks, final Form form, final Component component) { return new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { return !followLinks; } @Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { if (ignoreErrors) { handler.proceed(); } else { handler.cancel(); form.dispatchErrorOccurredEvent(component, "WebView", ErrorMessages.ERROR_WEBVIEW_SSL_ERROR); } } }; } }