package tv.emby.embyatv.startup; import android.Manifest; import android.app.Activity; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.preference.PreferenceManager; import android.support.annotation.NonNull; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import java.util.ArrayList; import java.util.List; import mediabrowser.apiinteraction.ApiEventListener; import mediabrowser.apiinteraction.ConnectionResult; import mediabrowser.apiinteraction.IConnectionManager; import mediabrowser.apiinteraction.Response; import mediabrowser.apiinteraction.android.AndroidConnectionManager; import mediabrowser.apiinteraction.android.AndroidDevice; import mediabrowser.apiinteraction.android.GsonJsonSerializer; import mediabrowser.apiinteraction.android.VolleyHttpClient; import mediabrowser.apiinteraction.android.profiles.AndroidProfile; import mediabrowser.apiinteraction.playback.PlaybackManager; import mediabrowser.model.apiclient.ConnectionState; import mediabrowser.model.apiclient.ServerInfo; import mediabrowser.model.dto.UserDto; import mediabrowser.model.logging.ILogger; import mediabrowser.model.serialization.IJsonSerializer; import mediabrowser.model.session.ClientCapabilities; import mediabrowser.model.session.GeneralCommandType; import tv.emby.embyatv.BuildConfig; import tv.emby.embyatv.R; import tv.emby.embyatv.TvApp; import tv.emby.embyatv.browsing.MainActivity; import tv.emby.embyatv.details.FullDetailsActivity; import tv.emby.embyatv.eventhandling.TvApiEventListener; import tv.emby.embyatv.playback.MediaManager; import tv.emby.embyatv.util.Utils; public class StartupActivity extends Activity { private static final int NETWORK_PERMISSION = 1; private TvApp application; private ILogger logger; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.fragment_startup); application = (TvApp) getApplicationContext(); logger = application.getLogger(); //Migrate prefs if (Integer.parseInt(application.getConfigVersion()) < 2) { application.getPrefs().edit().putString("pref_vlc_max_res", "2900").commit(); application.getSystemPrefs().edit().putString("sys_pref_config_version", "2").commit(); } if (Integer.parseInt(application.getConfigVersion()) < 3) { application.getPrefs().edit().putString("pref_max_bitrate", "0").commit(); application.getSystemPrefs().edit().putString("sys_pref_config_version", "3").commit(); } //Ensure we have prefs PreferenceManager.setDefaultValues(this, R.xml.preferences, false); //Ensure basic permissions if (Build.VERSION.SDK_INT >= 23 && (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_NETWORK_STATE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED)) { logger.Info("Requesting network permissions"); ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_NETWORK_STATE, Manifest.permission.INTERNET}, NETWORK_PERMISSION); } else { logger.Info("Basic network permissions are granted"); start(); } } private void start() { if (application.getCurrentUser() != null && application.getApiClient() != null && MediaManager.isPlayingAudio()) { // go straight into last connection Intent intent = new Intent(this, MainActivity.class); startActivity(intent); } else { //clear audio queue in case left over from last run MediaManager.clearAudioQueue(); MediaManager.clearVideoQueue(); establishConnection(this); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { switch (requestCode) { case NETWORK_PERMISSION: { // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // permission was granted, yay! start(); } else { // permission denied, boo! Disable the // functionality that depends on this permission. Utils.showToast(this, "Application cannot continue without network"); finish(); } return; } // other 'case' lines to check for other // permissions this app might request } } private void establishConnection(final Activity activity){ // The underlying http stack. Developers can inject their own if desired VolleyHttpClient volleyHttpClient = new VolleyHttpClient(logger, application); TvApp.getApplication().setHttpClient(volleyHttpClient); ClientCapabilities capabilities = new ClientCapabilities(); ArrayList<String> playableTypes = new ArrayList<>(); playableTypes.add("Video"); playableTypes.add("Audio"); ArrayList<String> supportedCommands = new ArrayList<>(); supportedCommands.add(GeneralCommandType.DisplayContent.toString()); supportedCommands.add(GeneralCommandType.Mute.toString()); supportedCommands.add(GeneralCommandType.Unmute.toString()); supportedCommands.add(GeneralCommandType.ToggleMute.toString()); capabilities.setPlayableMediaTypes(playableTypes); capabilities.setSupportsContentUploading(false); capabilities.setSupportsSync(false); capabilities.setDeviceProfile(new AndroidProfile(Utils.getProfileOptions())); capabilities.setSupportsMediaControl(true); capabilities.setSupportedCommands(supportedCommands); capabilities.setAppStoreUrl(Utils.getStoreUrl()); capabilities.setIconUrl("https://raw.githubusercontent.com/MediaBrowser/MediaBrowser.Android/master/servericon.png"); IJsonSerializer jsonSerializer = new GsonJsonSerializer(); ApiEventListener apiEventListener = new TvApiEventListener(); final IConnectionManager connectionManager = new AndroidConnectionManager(application, jsonSerializer, logger, volleyHttpClient, "AndroidTv", BuildConfig.VERSION_NAME, new AndroidDevice(application), capabilities, apiEventListener); application.setConnectionManager(connectionManager); application.setSerializer((GsonJsonSerializer) jsonSerializer); application.setPlaybackManager(new PlaybackManager(new AndroidDevice(application), logger)); //See if we are coming in via direct entry application.setDirectItemId(getIntent().getStringExtra("ItemId")); //Load any saved login creds application.setConfiguredAutoCredentials(Utils.GetSavedLoginCredentials(application.getDirectItemId() == null ? "tv.mediabrowser.login.json" : "tv.emby.lastlogin.json")); //And use those credentials if option is set if (application.getIsAutoLoginConfigured() || application.getDirectItemId() != null) { //Auto login as configured user - first connect to server connectionManager.Connect(application.getConfiguredAutoCredentials().getServerInfo(), new Response<ConnectionResult>() { @Override public void onResponse(ConnectionResult response) { if (response.getState() == ConnectionState.Unavailable) { Utils.showToast( activity, "Unable to connect to configured server "+application.getConfiguredAutoCredentials().getServerInfo().getName()); connectAutomatically(connectionManager, activity); return; } // Connected to server - load user and prompt for pw if necessary application.setLoginApiClient(response.getApiClient()); response.getApiClient().GetUserAsync(application.getConfiguredAutoCredentials().getUserDto().getId(), new Response<UserDto>() { @Override public void onResponse(final UserDto response) { application.setCurrentUser(response); if (application.getDirectItemId() != null) { application.validate(); application.determineAutoBitrate(); if (response.getHasPassword() && (!application.getIsAutoLoginConfigured() || (application.getPrefs().getBoolean("pref_auto_pw_prompt", false)))) { //Need to prompt for pw Utils.processPasswordEntry(activity, response, application.getDirectItemId()); } else { //Can just go right into details Intent detailsIntent = new Intent(activity, FullDetailsActivity.class); detailsIntent.putExtra("ItemId", application.getDirectItemId()); startActivity(detailsIntent); } } else { if (response.getHasPassword() && application.getPrefs().getBoolean("pref_auto_pw_prompt", false)) { Utils.processPasswordEntry(activity, response); } else { Intent intent = new Intent(activity, MainActivity.class); activity.startActivity(intent); } } } @Override public void onError(Exception exception) { application.getLogger().ErrorException("Error Signing in", exception); Utils.reportError(activity, "Error Signing In"); new Handler().postDelayed(new Runnable() { @Override public void run() { connectAutomatically(connectionManager, activity); } }, 5000); } }); } @Override public void onError(Exception exception) { Utils.showToast( activity, "Unable to connect to configured server "+application.getConfiguredAutoCredentials().getServerInfo().getName()); connectAutomatically(connectionManager, activity); } }); } else { connectAutomatically(connectionManager, activity); } } private void connectAutomatically(final IConnectionManager connectionManager, final Activity activity){ connectionManager.Connect(new Response<ConnectionResult>() { @Override public void onResponse(final ConnectionResult response) { Utils.handleConnectionResponse(connectionManager, activity, response); } @Override public void onError(Exception exception) { Utils.reportError(activity, "Error connecting"); } }); } }