From 738e2ac3443fa256cbdb7c452cf28c93bf9dfdd5 Mon Sep 17 00:00:00 2001
From: Christian Schabesberger <chris.schabesberger@mailbox.org>
Date: Mon, 12 Feb 2018 19:44:35 +0100
Subject: [PATCH] merge RouterActivity and RouterVideoActivity

---
 app/src/main/AndroidManifest.xml              | 113 ++---
 .../org/schabi/newpipe/RouterActivity.java    | 460 ++++++++++++++++--
 .../schabi/newpipe/RouterPlayerActivity.java  | 413 ----------------
 .../ic_info_outline_black_24dp.png            | Bin 0 -> 487 bytes
 .../ic_info_outline_white_24dp.png            | Bin 0 -> 485 bytes
 .../ic_info_outline_black_24dp.png            | Bin 0 -> 323 bytes
 .../ic_info_outline_white_24dp.png            | Bin 0 -> 320 bytes
 .../ic_info_outline_black_24dp.png            | Bin 0 -> 640 bytes
 .../ic_info_outline_white_24dp.png            | Bin 0 -> 655 bytes
 .../ic_info_outline_black_24dp.png            | Bin 0 -> 940 bytes
 .../ic_info_outline_white_24dp.png            | Bin 0 -> 953 bytes
 .../ic_info_outline_black_24dp.png            | Bin 0 -> 1256 bytes
 .../ic_info_outline_white_24dp.png            | Bin 0 -> 1279 bytes
 app/src/main/res/values/attrs.xml             |   1 +
 app/src/main/res/values/settings_keys.xml     |   1 +
 app/src/main/res/values/strings.xml           |   1 +
 app/src/main/res/values/styles.xml            |   2 +
 17 files changed, 465 insertions(+), 526 deletions(-)
 delete mode 100644 app/src/main/java/org/schabi/newpipe/RouterPlayerActivity.java
 create mode 100644 app/src/main/res/drawable-hdpi/ic_info_outline_black_24dp.png
 create mode 100644 app/src/main/res/drawable-hdpi/ic_info_outline_white_24dp.png
 create mode 100644 app/src/main/res/drawable-mdpi/ic_info_outline_black_24dp.png
 create mode 100644 app/src/main/res/drawable-mdpi/ic_info_outline_white_24dp.png
 create mode 100644 app/src/main/res/drawable-xhdpi/ic_info_outline_black_24dp.png
 create mode 100644 app/src/main/res/drawable-xhdpi/ic_info_outline_white_24dp.png
 create mode 100644 app/src/main/res/drawable-xxhdpi/ic_info_outline_black_24dp.png
 create mode 100644 app/src/main/res/drawable-xxhdpi/ic_info_outline_white_24dp.png
 create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_info_outline_black_24dp.png
 create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_info_outline_white_24dp.png

diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index bc3dc62e6..f286ee76c 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -122,8 +122,12 @@
 
         <activity
             android:name=".RouterActivity"
+            android:excludeFromRecents="true"
+            android:label="@string/preferred_player_share_menu_title"
             android:taskAffinity=""
             android:theme="@style/RouterActivityThemeDark">
+
+            <!-- Youtube filter -->
             <intent-filter>
                 <action android:name="android.intent.action.VIEW"/>
                 <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH"/>
@@ -169,6 +173,41 @@
                 <category android:name="android.intent.category.DEFAULT"/>
                 <category android:name="android.intent.category.BROWSABLE"/>
 
+                <data android:scheme="vnd.youtube"/>
+                <data android:scheme="vnd.youtube.launch"/>
+            </intent-filter>
+
+            <!-- Hooktube filter -->
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW"/>
+                <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH"/>
+                <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
+
+                <category android:name="android.intent.category.DEFAULT"/>
+                <category android:name="android.intent.category.BROWSABLE"/>
+
+                <data android:scheme="http"/>
+                <data android:scheme="https"/>
+                <data android:host="hooktube.com"/>
+                <data android:host="*.youtube.com"/>
+                <!-- video prefix -->
+                <data android:pathPrefix="/v/"/>
+                <data android:pathPrefix="/embed/"/>
+                <data android:pathPrefix="/watch"/>
+                <!-- channel prefix -->
+                <data android:pathPrefix="/channel/"/>
+                <data android:pathPrefix="/user/"/>
+            </intent-filter>
+
+            <!-- Soundcloud filter -->
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW"/>
+                <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH"/>
+                <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
+
+                <category android:name="android.intent.category.DEFAULT"/>
+                <category android:name="android.intent.category.BROWSABLE"/>
+
                 <data android:scheme="http"/>
                 <data android:scheme="https"/>
                 <data android:host="soundcloud.com"/>
@@ -176,17 +215,8 @@
                 <data android:host="www.soundcloud.com"/>
                 <data android:pathPrefix="/"/>
             </intent-filter>
-            <intent-filter>
-                <action android:name="android.intent.action.VIEW"/>
-                <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH"/>
-                <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
 
-                <category android:name="android.intent.category.DEFAULT"/>
-                <category android:name="android.intent.category.BROWSABLE"/>
-
-                <data android:scheme="vnd.youtube"/>
-                <data android:scheme="vnd.youtube.launch"/>
-            </intent-filter>
+            <!-- Share filter -->
             <intent-filter>
                 <action android:name="android.intent.action.SEND"/>
                 <category android:name="android.intent.category.DEFAULT"/>
@@ -195,68 +225,7 @@
         </activity>
 
         <service
-            android:name=".RouterPlayerActivity$FetcherService"
+            android:name=".RouterActivity$FetcherService"
             android:exported="false"/>
-
-        <activity
-            android:name=".RouterPlayerActivity"
-            android:excludeFromRecents="true"
-            android:label="@string/preferred_player_share_menu_title"
-            android:taskAffinity=""
-            android:theme="@style/RouterActivityThemeDark">
-            <intent-filter>
-                <action android:name="android.intent.action.VIEW"/>
-                <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH"/>
-                <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
-
-                <category android:name="android.intent.category.DEFAULT"/>
-                <category android:name="android.intent.category.BROWSABLE"/>
-
-                <data android:scheme="http"/>
-                <data android:scheme="https"/>
-                <data android:host="youtube.com"/>
-                <data android:host="m.youtube.com"/>
-                <data android:host="www.youtube.com"/>
-                <!-- video prefix -->
-                <data android:pathPrefix="/v/"/>
-                <data android:pathPrefix="/embed/"/>
-                <data android:pathPrefix="/watch"/>
-                <data android:pathPrefix="/attribution_link"/>
-                <!-- channel prefix -->
-                <data android:pathPrefix="/channel/"/>
-                <data android:pathPrefix="/user/"/>
-                <!-- playlist prefix -->
-                <data android:pathPrefix="/playlist"/>
-            </intent-filter>
-            <intent-filter>
-                <action android:name="android.intent.action.VIEW"/>
-                <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH"/>
-                <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
-
-                <category android:name="android.intent.category.DEFAULT"/>
-                <category android:name="android.intent.category.BROWSABLE"/>
-
-                <data android:scheme="http"/>
-                <data android:scheme="https"/>
-                <data android:host="youtu.be"/>
-                <data android:pathPrefix="/"/>
-            </intent-filter>
-            <intent-filter>
-                <action android:name="android.intent.action.VIEW"/>
-                <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH"/>
-                <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
-
-                <category android:name="android.intent.category.DEFAULT"/>
-                <category android:name="android.intent.category.BROWSABLE"/>
-
-                <data android:scheme="vnd.youtube"/>
-                <data android:scheme="vnd.youtube.launch"/>
-            </intent-filter>
-            <intent-filter>
-                <action android:name="android.intent.action.SEND"/>
-                <category android:name="android.intent.category.DEFAULT"/>
-                <data android:mimeType="text/plain"/>
-            </intent-filter>
-        </activity>
     </application>
 </manifest>
\ No newline at end of file
diff --git a/app/src/main/java/org/schabi/newpipe/RouterActivity.java b/app/src/main/java/org/schabi/newpipe/RouterActivity.java
index 8aaa248dd..0586a86be 100644
--- a/app/src/main/java/org/schabi/newpipe/RouterActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/RouterActivity.java
@@ -1,51 +1,80 @@
 package org.schabi.newpipe;
 
+import android.app.IntentService;
+import android.content.DialogInterface;
 import android.content.Intent;
+import android.content.SharedPreferences;
 import android.os.Bundle;
+import android.os.PersistableBundle;
+import android.preference.PreferenceManager;
+import android.support.annotation.DrawableRes;
+import android.support.annotation.Nullable;
+import android.support.v4.app.NotificationCompat;
+import android.support.v7.app.AlertDialog;
 import android.support.v7.app.AppCompatActivity;
 import android.text.TextUtils;
+import android.util.Log;
+import android.view.ContextThemeWrapper;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.RadioButton;
+import android.widget.RadioGroup;
 import android.widget.Toast;
 
+import org.schabi.newpipe.extractor.Info;
+import org.schabi.newpipe.extractor.NewPipe;
+import org.schabi.newpipe.extractor.ServiceList;
+import org.schabi.newpipe.extractor.StreamingService;
+import org.schabi.newpipe.extractor.StreamingService.LinkType;
+import org.schabi.newpipe.extractor.channel.ChannelInfo;
 import org.schabi.newpipe.extractor.exceptions.ExtractionException;
+import org.schabi.newpipe.extractor.playlist.PlaylistInfo;
+import org.schabi.newpipe.extractor.stream.StreamInfo;
+import org.schabi.newpipe.player.helper.PlayerHelper;
+import org.schabi.newpipe.playlist.ChannelPlayQueue;
+import org.schabi.newpipe.playlist.PlayQueue;
+import org.schabi.newpipe.playlist.PlaylistPlayQueue;
+import org.schabi.newpipe.playlist.SinglePlayQueue;
 import org.schabi.newpipe.report.UserAction;
 import org.schabi.newpipe.util.ExtractorHelper;
 import org.schabi.newpipe.util.NavigationHelper;
+import org.schabi.newpipe.util.PermissionHelper;
+import org.schabi.newpipe.util.ThemeHelper;
 
+import java.io.Serializable;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashSet;
 
 import icepick.Icepick;
 import icepick.State;
 import io.reactivex.Observable;
+import io.reactivex.Single;
 import io.reactivex.android.schedulers.AndroidSchedulers;
 import io.reactivex.disposables.CompositeDisposable;
+import io.reactivex.disposables.Disposable;
+import io.reactivex.functions.Consumer;
 import io.reactivex.schedulers.Schedulers;
 
-/*
- * Copyright (C) Christian Schabesberger 2017 <chris.schabesberger@mailbox.org>
- * RouterActivity.java is part of NewPipe.
- *
- * NewPipe is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * NewPipe is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with NewPipe.  If not, see <http://www.gnu.org/licenses/>.
- */
+import static org.schabi.newpipe.util.ThemeHelper.resolveResourceIdFromAttr;
 
 /**
- * This Acitivty is designed to route share/open intents to the specified service, and
- * to the part of the service which can handle the url.
+ * Get the url from the intent and open it in the chosen preferred player
  */
 public class RouterActivity extends AppCompatActivity {
 
     @State
+    protected int currentServiceId = -1;
+    private StreamingService currentService;
+    @State
+    protected LinkType currentLinkType;
+    @State
+    protected int selectedRadioPosition = -1;
+    protected int selectedPreviously = -1;
+
     protected String currentUrl;
     protected CompositeDisposable disposables = new CompositeDisposable();
 
@@ -62,6 +91,10 @@ public class RouterActivity extends AppCompatActivity {
                 finish();
             }
         }
+
+        setTheme(ThemeHelper.isLightThemeSelected(this)
+                ? R.style.RouterActivityThemeLight
+                : R.style.RouterActivityThemeDark);
     }
 
     @Override
@@ -73,25 +106,43 @@ public class RouterActivity extends AppCompatActivity {
     @Override
     protected void onStart() {
         super.onStart();
+
         handleUrl(currentUrl);
     }
 
-    protected void handleUrl(String url) {
-        disposables.add(Observable
-                .fromCallable(() -> NavigationHelper.getIntentByLink(this, url))
-                .subscribeOn(Schedulers.io())
-                .observeOn(AndroidSchedulers.mainThread())
-                .subscribe(intent -> {
-                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
-                    startActivity(intent);
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
 
-                    finish();
-                }, this::handleError)
-        );
+        disposables.clear();
     }
 
-    protected void handleError(Throwable error) {
+    private void handleUrl(String url) {
+        disposables.add(Observable
+                .fromCallable(() -> {
+                    if (currentServiceId == -1) {
+                        currentService = NewPipe.getServiceByUrl(url);
+                        currentServiceId = currentService.getServiceId();
+                        currentLinkType = currentService.getLinkTypeByUrl(url);
+                        currentUrl = NavigationHelper.getCleanUrl(currentService, url, currentLinkType);
+                    } else {
+                        currentService = NewPipe.getService(currentServiceId);
+                    }
+
+                    return currentLinkType != LinkType.NONE;
+                })
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe(result -> {
+                    if (result) {
+                        onSuccess();
+                    } else {
+                        onError();
+                    }
+                }, this::handleError));
+    }
+
+    private void handleError(Throwable error) {
         error.printStackTrace();
 
         if (error instanceof ExtractionException) {
@@ -103,11 +154,339 @@ public class RouterActivity extends AppCompatActivity {
         finish();
     }
 
-    @Override
-    protected void onDestroy() {
-        super.onDestroy();
+    private void onError() {
+        Toast.makeText(this, R.string.url_not_supported_toast, Toast.LENGTH_LONG).show();
+        finish();
+    }
 
-        disposables.clear();
+    protected void onSuccess() {
+        final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
+        boolean isExtVideoEnabled = preferences.getBoolean(getString(R.string.use_external_video_player_key), false);
+        boolean isExtAudioEnabled = preferences.getBoolean(getString(R.string.use_external_audio_player_key), false);
+
+        if ((isExtAudioEnabled || isExtVideoEnabled) && currentLinkType != LinkType.STREAM) {
+            Toast.makeText(this, R.string.external_player_unsupported_link_type, Toast.LENGTH_LONG).show();
+            finish();
+            return;
+        }
+
+        // TODO: Add some sort of "capabilities" field to services (audio only, video and audio, etc.)
+        if (currentService == ServiceList.SoundCloud.getService()) {
+            handleChoice(getString(R.string.background_player_key));
+            return;
+        }
+
+        final String playerChoiceKey = preferences.getString(getString(R.string.preferred_player_key), getString(R.string.preferred_player_default));
+        final String alwaysAskKey = getString(R.string.always_ask_player_key);
+
+        if (playerChoiceKey.equals(alwaysAskKey)) {
+            showDialog();
+        } else {
+            handleChoice(playerChoiceKey);
+        }
+    }
+
+    private void showDialog() {
+        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
+        final ContextThemeWrapper themeWrapper = new ContextThemeWrapper(this,
+                ThemeHelper.isLightThemeSelected(this) ? R.style.LightTheme : R.style.DarkTheme);
+
+        LayoutInflater inflater = LayoutInflater.from(themeWrapper);
+        final LinearLayout rootLayout = (LinearLayout) inflater.inflate(R.layout.preferred_player_dialog_view, null, false);
+        final RadioGroup radioGroup = rootLayout.findViewById(android.R.id.list);
+
+        final AdapterChoiceItem[] choices = {
+                new AdapterChoiceItem(getString(R.string.info_screen_key), getString(R.string.info_screen),
+                        resolveResourceIdFromAttr(themeWrapper, R.attr.info)),
+                new AdapterChoiceItem(getString(R.string.video_player_key), getString(R.string.video_player),
+                        resolveResourceIdFromAttr(themeWrapper, R.attr.play)),
+                new AdapterChoiceItem(getString(R.string.background_player_key), getString(R.string.background_player),
+                        resolveResourceIdFromAttr(themeWrapper, R.attr.audio)),
+                new AdapterChoiceItem(getString(R.string.popup_player_key), getString(R.string.popup_player),
+                        resolveResourceIdFromAttr(themeWrapper, R.attr.popup))
+        };
+
+        final DialogInterface.OnClickListener dialogButtonsClickListener = (dialog, which) -> {
+            final int indexOfChild = radioGroup.indexOfChild(
+                    radioGroup.findViewById(radioGroup.getCheckedRadioButtonId()));
+            final AdapterChoiceItem choice = choices[indexOfChild];
+
+            handleChoice(choice.key);
+
+            if (which == DialogInterface.BUTTON_POSITIVE) {
+                preferences.edit().putString(getString(R.string.preferred_player_key), choice.key).apply();
+            }
+        };
+
+        final AlertDialog alertDialog = new AlertDialog.Builder(themeWrapper)
+                .setTitle(R.string.preferred_player_share_menu_title)
+                .setView(radioGroup)
+                .setCancelable(true)
+                .setNegativeButton(R.string.just_once, dialogButtonsClickListener)
+                .setPositiveButton(R.string.always, dialogButtonsClickListener)
+                .setOnDismissListener((dialog) -> finish())
+                .create();
+
+        alertDialog.setOnShowListener(dialog -> {
+            setDialogButtonsState(alertDialog, radioGroup.getCheckedRadioButtonId() != -1);
+        });
+
+        radioGroup.setOnCheckedChangeListener((group, checkedId) -> setDialogButtonsState(alertDialog, true));
+        final View.OnClickListener radioButtonsClickListener = v -> {
+            final int indexOfChild = radioGroup.indexOfChild(v);
+            if (indexOfChild == -1) return;
+
+            selectedPreviously = selectedRadioPosition;
+            selectedRadioPosition = indexOfChild;
+
+            if (selectedPreviously == selectedRadioPosition) {
+                handleChoice(choices[selectedRadioPosition].key);
+            }
+        };
+
+        int id = 12345;
+        for (AdapterChoiceItem item : choices) {
+            final RadioButton radioButton = (RadioButton) inflater.inflate(R.layout.list_radio_icon_item, null);
+            radioButton.setText(item.description);
+            radioButton.setCompoundDrawablesWithIntrinsicBounds(item.icon, 0, 0, 0);
+            radioButton.setChecked(false);
+            radioButton.setId(id++);
+            radioButton.setLayoutParams(new RadioGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+            radioButton.setOnClickListener(radioButtonsClickListener);
+            radioGroup.addView(radioButton);
+        }
+
+        if (selectedRadioPosition == -1) {
+            final String lastSelectedPlayer = preferences.getString(getString(R.string.preferred_player_last_selected_key), null);
+            if (!TextUtils.isEmpty(lastSelectedPlayer)) {
+                for (int i = 0; i < choices.length; i++) {
+                    AdapterChoiceItem c = choices[i];
+                    if (lastSelectedPlayer.equals(c.key)) {
+                        selectedRadioPosition = i;
+                        break;
+                    }
+                }
+            }
+        }
+
+        selectedRadioPosition = Math.min(Math.max(-1, selectedRadioPosition), choices.length - 1);
+        if (selectedRadioPosition != -1) {
+            ((RadioButton) radioGroup.getChildAt(selectedRadioPosition)).setChecked(true);
+        }
+        selectedPreviously = selectedRadioPosition;
+
+        alertDialog.show();
+    }
+
+    private void setDialogButtonsState(AlertDialog dialog, boolean state) {
+        final Button negativeButton = dialog.getButton(DialogInterface.BUTTON_NEGATIVE);
+        final Button positiveButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
+        if (negativeButton == null || positiveButton == null) return;
+
+        negativeButton.setEnabled(state);
+        positiveButton.setEnabled(state);
+    }
+
+    private void handleChoice(final String playerChoiceKey) {
+        if (Arrays.asList(getResources().getStringArray(R.array.preferred_player_values_list)).contains(playerChoiceKey)) {
+            PreferenceManager.getDefaultSharedPreferences(this).edit()
+                    .putString(getString(R.string.preferred_player_last_selected_key), playerChoiceKey).apply();
+        }
+
+        if (playerChoiceKey.equals(getString(R.string.popup_player_key)) && !PermissionHelper.isPopupEnabled(this)) {
+            PermissionHelper.showPopupEnablementToast(this);
+            finish();
+            return;
+        }
+
+        // stop and bypass FetcherService if InfoScreen was selected since
+        // StreamDetailFragment can fetch data itself
+        if(playerChoiceKey.equals(getString(R.string.info_screen_key))) {
+            disposables.add(Observable
+                    .fromCallable(() -> NavigationHelper.getIntentByLink(this, currentUrl))
+                    .subscribeOn(Schedulers.io())
+                    .observeOn(AndroidSchedulers.mainThread())
+                    .subscribe(intent -> {
+                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+                        startActivity(intent);
+
+                        finish();
+                    }, this::handleError)
+            );
+            return;
+        }
+
+        final Intent intent = new Intent(this, FetcherService.class);
+        intent.putExtra(FetcherService.KEY_CHOICE,
+                new Choice(currentService.getServiceId(),
+                        currentLinkType,
+                        currentUrl,
+                        playerChoiceKey));
+        startService(intent);
+
+        finish();
+    }
+
+    private static class AdapterChoiceItem {
+        final String description, key;
+        @DrawableRes
+        final int icon;
+
+        AdapterChoiceItem(String key, String description, int icon) {
+            this.description = description;
+            this.key = key;
+            this.icon = icon;
+        }
+    }
+
+    private static class Choice implements Serializable {
+        final int serviceId;
+        final String url, playerChoice;
+        final LinkType linkType;
+
+        Choice(int serviceId, LinkType linkType, String url, String playerChoice) {
+            this.serviceId = serviceId;
+            this.linkType = linkType;
+            this.url = url;
+            this.playerChoice = playerChoice;
+        }
+
+        @Override
+        public String toString() {
+            return serviceId + ":" + url + " > " + linkType + " ::: " + playerChoice;
+        }
+    }
+
+    /*//////////////////////////////////////////////////////////////////////////
+    // Service Fetcher
+    //////////////////////////////////////////////////////////////////////////*/
+
+    public static class FetcherService extends IntentService {
+
+        private static final int ID = 456;
+        public static final String KEY_CHOICE = "key_choice";
+        private Disposable fetcher;
+
+        public FetcherService() {
+            super(FetcherService.class.getSimpleName());
+        }
+
+        @Override
+        public void onCreate() {
+            super.onCreate();
+            startForeground(ID, createNotification().build());
+        }
+
+        @Override
+        protected void onHandleIntent(@Nullable Intent intent) {
+            if (intent == null) return;
+
+            final Serializable serializable = intent.getSerializableExtra(KEY_CHOICE);
+            if (!(serializable instanceof Choice)) return;
+            Choice playerChoice = (Choice) serializable;
+            handleChoice(playerChoice);
+        }
+
+        public void handleChoice(Choice choice) {
+            Single<? extends Info> single = null;
+            UserAction userAction = UserAction.SOMETHING_ELSE;
+
+            switch (choice.linkType) {
+                case STREAM:
+                    single = ExtractorHelper.getStreamInfo(choice.serviceId, choice.url, false);
+                    userAction = UserAction.REQUESTED_STREAM;
+                    break;
+                case CHANNEL:
+                    single = ExtractorHelper.getChannelInfo(choice.serviceId, choice.url, false);
+                    userAction = UserAction.REQUESTED_CHANNEL;
+                    break;
+                case PLAYLIST:
+                    single = ExtractorHelper.getPlaylistInfo(choice.serviceId, choice.url, false);
+                    userAction = UserAction.REQUESTED_PLAYLIST;
+                    break;
+            }
+
+
+            if (single != null) {
+                final UserAction finalUserAction = userAction;
+                final Consumer<Info> resultHandler = getResultHandler(choice);
+                fetcher = single
+                        .observeOn(AndroidSchedulers.mainThread())
+                        .subscribe(info -> {
+                            resultHandler.accept(info);
+                            if (fetcher != null) fetcher.dispose();
+                        }, throwable -> ExtractorHelper.handleGeneralException(this,
+                                choice.serviceId, choice.url, throwable, finalUserAction, ", opened with " + choice.playerChoice));
+            }
+        }
+
+        public Consumer<Info> getResultHandler(Choice choice) {
+            return info -> {
+                final String videoPlayerKey = getString(R.string.video_player_key);
+                final String backgroundPlayerKey = getString(R.string.background_player_key);
+                final String popupPlayerKey = getString(R.string.popup_player_key);
+
+                final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
+                boolean isExtVideoEnabled = preferences.getBoolean(getString(R.string.use_external_video_player_key), false);
+                boolean isExtAudioEnabled = preferences.getBoolean(getString(R.string.use_external_audio_player_key), false);
+                boolean useOldVideoPlayer = PlayerHelper.isUsingOldPlayer(this);
+
+                PlayQueue playQueue;
+                String playerChoice = choice.playerChoice;
+
+                if (info instanceof StreamInfo) {
+                    if (playerChoice.equals(backgroundPlayerKey) && isExtAudioEnabled) {
+                        NavigationHelper.playOnExternalAudioPlayer(this, (StreamInfo) info);
+
+                    } else if (playerChoice.equals(videoPlayerKey) && isExtVideoEnabled) {
+                        NavigationHelper.playOnExternalVideoPlayer(this, (StreamInfo) info);
+
+                    } else if (playerChoice.equals(videoPlayerKey) && useOldVideoPlayer) {
+                        NavigationHelper.playOnOldVideoPlayer(this, (StreamInfo) info);
+
+                    } else {
+                        playQueue = new SinglePlayQueue((StreamInfo) info);
+
+                        if (playerChoice.equals(videoPlayerKey)) {
+                            NavigationHelper.playOnMainPlayer(this, playQueue);
+                        } else if (playerChoice.equals(backgroundPlayerKey)) {
+                            NavigationHelper.enqueueOnBackgroundPlayer(this, playQueue, true);
+                        } else if (playerChoice.equals(popupPlayerKey)) {
+                            NavigationHelper.enqueueOnPopupPlayer(this, playQueue, true);
+                        }
+                    }
+                }
+
+                if (info instanceof ChannelInfo || info instanceof PlaylistInfo) {
+                    playQueue = info instanceof ChannelInfo ? new ChannelPlayQueue((ChannelInfo) info) : new PlaylistPlayQueue((PlaylistInfo) info);
+
+                    if (playerChoice.equals(videoPlayerKey)) {
+                        NavigationHelper.playOnMainPlayer(this, playQueue);
+                    } else if (playerChoice.equals(backgroundPlayerKey)) {
+                        NavigationHelper.playOnBackgroundPlayer(this, playQueue);
+                    } else if (playerChoice.equals(popupPlayerKey)) {
+                        NavigationHelper.playOnPopupPlayer(this, playQueue);
+                    }
+                }
+            };
+        }
+
+        @Override
+        public void onDestroy() {
+            super.onDestroy();
+            stopForeground(true);
+            if (fetcher != null) fetcher.dispose();
+        }
+
+        private NotificationCompat.Builder createNotification() {
+            return new NotificationCompat.Builder(this, getString(R.string.notification_channel_id))
+                    .setOngoing(true)
+                    .setSmallIcon(R.drawable.ic_newpipe_triangle_white)
+                    .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
+                    .setContentTitle(getString(R.string.preferred_player_fetcher_notification_title))
+                    .setContentText(getString(R.string.preferred_player_fetcher_notification_message));
+        }
     }
 
     /*//////////////////////////////////////////////////////////////////////////
@@ -119,9 +498,9 @@ public class RouterActivity extends AppCompatActivity {
      * brackets (\p{P}). See http://www.regular-expressions.info/unicode.html for
      * more details.
      */
-    protected final static String REGEX_REMOVE_FROM_URL = "[\\p{Z}\\p{P}]";
+    private final static String REGEX_REMOVE_FROM_URL = "[\\p{Z}\\p{P}]";
 
-    protected String getUrl(Intent intent) {
+    private String getUrl(Intent intent) {
         // first gather data and find service
         String videoUrl = null;
         if (intent.getData() != null) {
@@ -137,7 +516,7 @@ public class RouterActivity extends AppCompatActivity {
         return videoUrl;
     }
 
-    protected String removeHeadingGibberish(final String input) {
+    private String removeHeadingGibberish(final String input) {
         int start = 0;
         for (int i = input.indexOf("://") - 1; i >= 0; i--) {
             if (!input.substring(i, i + 1).matches("\\p{L}")) {
@@ -148,7 +527,7 @@ public class RouterActivity extends AppCompatActivity {
         return input.substring(start, input.length());
     }
 
-    protected String trim(final String input) {
+    private String trim(final String input) {
         if (input == null || input.length() < 1) {
             return input;
         } else {
@@ -188,5 +567,4 @@ public class RouterActivity extends AppCompatActivity {
         }
         return result.toArray(new String[result.size()]);
     }
-
 }
diff --git a/app/src/main/java/org/schabi/newpipe/RouterPlayerActivity.java b/app/src/main/java/org/schabi/newpipe/RouterPlayerActivity.java
deleted file mode 100644
index 7196e413d..000000000
--- a/app/src/main/java/org/schabi/newpipe/RouterPlayerActivity.java
+++ /dev/null
@@ -1,413 +0,0 @@
-package org.schabi.newpipe;
-
-import android.app.IntentService;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.os.PersistableBundle;
-import android.preference.PreferenceManager;
-import android.support.annotation.DrawableRes;
-import android.support.annotation.Nullable;
-import android.support.v4.app.NotificationCompat;
-import android.support.v7.app.AlertDialog;
-import android.text.TextUtils;
-import android.view.ContextThemeWrapper;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.LinearLayout;
-import android.widget.RadioButton;
-import android.widget.RadioGroup;
-import android.widget.Toast;
-
-import org.schabi.newpipe.extractor.Info;
-import org.schabi.newpipe.extractor.NewPipe;
-import org.schabi.newpipe.extractor.ServiceList;
-import org.schabi.newpipe.extractor.StreamingService;
-import org.schabi.newpipe.extractor.StreamingService.LinkType;
-import org.schabi.newpipe.extractor.channel.ChannelInfo;
-import org.schabi.newpipe.extractor.exceptions.ExtractionException;
-import org.schabi.newpipe.extractor.playlist.PlaylistInfo;
-import org.schabi.newpipe.extractor.stream.StreamInfo;
-import org.schabi.newpipe.player.helper.PlayerHelper;
-import org.schabi.newpipe.playlist.ChannelPlayQueue;
-import org.schabi.newpipe.playlist.PlayQueue;
-import org.schabi.newpipe.playlist.PlaylistPlayQueue;
-import org.schabi.newpipe.playlist.SinglePlayQueue;
-import org.schabi.newpipe.report.UserAction;
-import org.schabi.newpipe.util.ExtractorHelper;
-import org.schabi.newpipe.util.NavigationHelper;
-import org.schabi.newpipe.util.PermissionHelper;
-import org.schabi.newpipe.util.ThemeHelper;
-
-import java.io.Serializable;
-import java.util.Arrays;
-
-import icepick.State;
-import io.reactivex.Observable;
-import io.reactivex.Single;
-import io.reactivex.android.schedulers.AndroidSchedulers;
-import io.reactivex.disposables.Disposable;
-import io.reactivex.functions.Consumer;
-import io.reactivex.schedulers.Schedulers;
-
-import static org.schabi.newpipe.util.ThemeHelper.resolveResourceIdFromAttr;
-
-/**
- * Get the url from the intent and open it in the chosen preferred player
- */
-public class RouterPlayerActivity extends RouterActivity {
-
-    @State
-    protected int currentServiceId = -1;
-    private StreamingService currentService;
-    @State
-    protected LinkType currentLinkType;
-    @State
-    protected int selectedRadioPosition = -1;
-    protected int selectedPreviously = -1;
-
-    @Override
-    public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
-        super.onCreate(savedInstanceState, persistentState);
-        setTheme(ThemeHelper.isLightThemeSelected(this) ? R.style.RouterActivityThemeLight : R.style.RouterActivityThemeDark);
-    }
-
-    @Override
-    protected void handleUrl(String url) {
-        disposables.add(Observable
-                .fromCallable(() -> {
-                    if (currentServiceId == -1) {
-                        currentService = NewPipe.getServiceByUrl(url);
-                        currentServiceId = currentService.getServiceId();
-                        currentLinkType = currentService.getLinkTypeByUrl(url);
-                        currentUrl = NavigationHelper.getCleanUrl(currentService, url, currentLinkType);
-                    } else {
-                        currentService = NewPipe.getService(currentServiceId);
-                    }
-
-                    return currentLinkType != LinkType.NONE;
-                })
-                .subscribeOn(Schedulers.io())
-                .observeOn(AndroidSchedulers.mainThread())
-                .subscribe(result -> {
-                    if (result) {
-                        onSuccess();
-                    } else {
-                        onError();
-                    }
-                }, this::handleError));
-    }
-
-    protected void onError() {
-        Toast.makeText(this, R.string.url_not_supported_toast, Toast.LENGTH_LONG).show();
-        finish();
-    }
-
-    protected void onSuccess() {
-        final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
-        boolean isExtVideoEnabled = preferences.getBoolean(getString(R.string.use_external_video_player_key), false);
-        boolean isExtAudioEnabled = preferences.getBoolean(getString(R.string.use_external_audio_player_key), false);
-
-        if ((isExtAudioEnabled || isExtVideoEnabled) && currentLinkType != LinkType.STREAM) {
-            Toast.makeText(this, R.string.external_player_unsupported_link_type, Toast.LENGTH_LONG).show();
-            finish();
-            return;
-        }
-
-        // TODO: Add some sort of "capabilities" field to services (audio only, video and audio, etc.)
-        if (currentService == ServiceList.SoundCloud.getService()) {
-            handleChoice(getString(R.string.background_player_key));
-            return;
-        }
-
-        final String playerChoiceKey = preferences.getString(getString(R.string.preferred_player_key), getString(R.string.preferred_player_default));
-        final String alwaysAskKey = getString(R.string.always_ask_player_key);
-
-        if (playerChoiceKey.equals(alwaysAskKey)) {
-            showDialog();
-        } else {
-            handleChoice(playerChoiceKey);
-        }
-    }
-
-    private void showDialog() {
-        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
-        final ContextThemeWrapper themeWrapper = new ContextThemeWrapper(this,
-                ThemeHelper.isLightThemeSelected(this) ? R.style.LightTheme : R.style.DarkTheme);
-
-        LayoutInflater inflater = LayoutInflater.from(themeWrapper);
-        final LinearLayout rootLayout = (LinearLayout) inflater.inflate(R.layout.preferred_player_dialog_view, null, false);
-        final RadioGroup radioGroup = rootLayout.findViewById(android.R.id.list);
-
-        final AdapterChoiceItem[] choices = {
-                new AdapterChoiceItem(getString(R.string.video_player_key), getString(R.string.video_player),
-                        resolveResourceIdFromAttr(themeWrapper, R.attr.play)),
-                new AdapterChoiceItem(getString(R.string.background_player_key), getString(R.string.background_player),
-                        resolveResourceIdFromAttr(themeWrapper, R.attr.audio)),
-                new AdapterChoiceItem(getString(R.string.popup_player_key), getString(R.string.popup_player),
-                        resolveResourceIdFromAttr(themeWrapper, R.attr.popup))
-        };
-
-        final DialogInterface.OnClickListener dialogButtonsClickListener = (dialog, which) -> {
-            final int indexOfChild = radioGroup.indexOfChild(radioGroup.findViewById(radioGroup.getCheckedRadioButtonId()));
-            final AdapterChoiceItem choice = choices[indexOfChild];
-
-            handleChoice(choice.key);
-
-            if (which == DialogInterface.BUTTON_POSITIVE) {
-                preferences.edit().putString(getString(R.string.preferred_player_key), choice.key).apply();
-            }
-        };
-
-        final AlertDialog alertDialog = new AlertDialog.Builder(themeWrapper)
-                .setTitle(R.string.preferred_player_share_menu_title)
-                .setView(radioGroup)
-                .setCancelable(true)
-                .setNegativeButton(R.string.just_once, dialogButtonsClickListener)
-                .setPositiveButton(R.string.always, dialogButtonsClickListener)
-                .setOnDismissListener((dialog) -> finish())
-                .create();
-
-        alertDialog.setOnShowListener(dialog -> {
-            setDialogButtonsState(alertDialog, radioGroup.getCheckedRadioButtonId() != -1);
-        });
-
-        radioGroup.setOnCheckedChangeListener((group, checkedId) -> setDialogButtonsState(alertDialog, true));
-        final View.OnClickListener radioButtonsClickListener = v -> {
-            final int indexOfChild = radioGroup.indexOfChild(v);
-            if (indexOfChild == -1) return;
-
-            selectedPreviously = selectedRadioPosition;
-            selectedRadioPosition = indexOfChild;
-
-            if (selectedPreviously == selectedRadioPosition) {
-                handleChoice(choices[selectedRadioPosition].key);
-            }
-        };
-
-        int id = 12345;
-        for (AdapterChoiceItem item : choices) {
-            final RadioButton radioButton = (RadioButton) inflater.inflate(R.layout.list_radio_icon_item, null);
-            radioButton.setText(item.description);
-            radioButton.setCompoundDrawablesWithIntrinsicBounds(item.icon, 0, 0, 0);
-            radioButton.setChecked(false);
-            radioButton.setId(id++);
-            radioButton.setLayoutParams(new RadioGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
-            radioButton.setOnClickListener(radioButtonsClickListener);
-            radioGroup.addView(radioButton);
-        }
-
-        if (selectedRadioPosition == -1) {
-            final String lastSelectedPlayer = preferences.getString(getString(R.string.preferred_player_last_selected_key), null);
-            if (!TextUtils.isEmpty(lastSelectedPlayer)) {
-                for (int i = 0; i < choices.length; i++) {
-                    AdapterChoiceItem c = choices[i];
-                    if (lastSelectedPlayer.equals(c.key)) {
-                        selectedRadioPosition = i;
-                        break;
-                    }
-                }
-            }
-        }
-
-        selectedRadioPosition = Math.min(Math.max(-1, selectedRadioPosition), choices.length - 1);
-        if (selectedRadioPosition != -1) {
-            ((RadioButton) radioGroup.getChildAt(selectedRadioPosition)).setChecked(true);
-        }
-        selectedPreviously = selectedRadioPosition;
-
-        alertDialog.show();
-    }
-
-    private void setDialogButtonsState(AlertDialog dialog, boolean state) {
-        final Button negativeButton = dialog.getButton(DialogInterface.BUTTON_NEGATIVE);
-        final Button positiveButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
-        if (negativeButton == null || positiveButton == null) return;
-
-        negativeButton.setEnabled(state);
-        positiveButton.setEnabled(state);
-    }
-
-    private void handleChoice(final String playerChoiceKey) {
-        if (Arrays.asList(getResources().getStringArray(R.array.preferred_player_values_list)).contains(playerChoiceKey)) {
-            PreferenceManager.getDefaultSharedPreferences(this).edit()
-                    .putString(getString(R.string.preferred_player_last_selected_key), playerChoiceKey).apply();
-        }
-
-        if (playerChoiceKey.equals(getString(R.string.popup_player_key)) && !PermissionHelper.isPopupEnabled(this)) {
-            PermissionHelper.showPopupEnablementToast(this);
-            finish();
-            return;
-        }
-
-        final Intent intent = new Intent(this, FetcherService.class);
-        intent.putExtra(FetcherService.KEY_CHOICE, new Choice(currentService.getServiceId(), currentLinkType, currentUrl, playerChoiceKey));
-        startService(intent);
-
-        finish();
-    }
-
-    private static class AdapterChoiceItem {
-        final String description, key;
-        @DrawableRes
-        final int icon;
-
-        AdapterChoiceItem(String key, String description, int icon) {
-            this.description = description;
-            this.key = key;
-            this.icon = icon;
-        }
-    }
-
-    private static class Choice implements Serializable {
-        final int serviceId;
-        final String url, playerChoice;
-        final LinkType linkType;
-
-        Choice(int serviceId, LinkType linkType, String url, String playerChoice) {
-            this.serviceId = serviceId;
-            this.linkType = linkType;
-            this.url = url;
-            this.playerChoice = playerChoice;
-        }
-
-        @Override
-        public String toString() {
-            return serviceId + ":" + url + " > " + linkType + " ::: " + playerChoice;
-        }
-    }
-
-    /*//////////////////////////////////////////////////////////////////////////
-    // Service Fetcher
-    //////////////////////////////////////////////////////////////////////////*/
-
-    public static class FetcherService extends IntentService {
-
-        private static final int ID = 456;
-        public static final String KEY_CHOICE = "key_choice";
-        private Disposable fetcher;
-
-        public FetcherService() {
-            super(FetcherService.class.getSimpleName());
-        }
-
-        @Override
-        public void onCreate() {
-            super.onCreate();
-            startForeground(ID, createNotification().build());
-        }
-
-        @Override
-        protected void onHandleIntent(@Nullable Intent intent) {
-            if (intent == null) return;
-
-            final Serializable serializable = intent.getSerializableExtra(KEY_CHOICE);
-            if (!(serializable instanceof Choice)) return;
-            Choice playerChoice = (Choice) serializable;
-            handleChoice(playerChoice);
-        }
-
-        public void handleChoice(Choice choice) {
-            Single<? extends Info> single = null;
-            UserAction userAction = UserAction.SOMETHING_ELSE;
-
-            switch (choice.linkType) {
-                case STREAM:
-                    single = ExtractorHelper.getStreamInfo(choice.serviceId, choice.url, false);
-                    userAction = UserAction.REQUESTED_STREAM;
-                    break;
-                case CHANNEL:
-                    single = ExtractorHelper.getChannelInfo(choice.serviceId, choice.url, false);
-                    userAction = UserAction.REQUESTED_CHANNEL;
-                    break;
-                case PLAYLIST:
-                    single = ExtractorHelper.getPlaylistInfo(choice.serviceId, choice.url, false);
-                    userAction = UserAction.REQUESTED_PLAYLIST;
-                    break;
-            }
-
-
-            if (single != null) {
-                final UserAction finalUserAction = userAction;
-                final Consumer<Info> resultHandler = getResultHandler(choice);
-                fetcher = single
-                        .observeOn(AndroidSchedulers.mainThread())
-                        .subscribe(info -> {
-                            resultHandler.accept(info);
-                            if (fetcher != null) fetcher.dispose();
-                        }, throwable -> ExtractorHelper.handleGeneralException(this,
-                                choice.serviceId, choice.url, throwable, finalUserAction, ", opened with " + choice.playerChoice));
-            }
-        }
-
-        public Consumer<Info> getResultHandler(Choice choice) {
-            return info -> {
-                final String videoPlayerKey = getString(R.string.video_player_key);
-                final String backgroundPlayerKey = getString(R.string.background_player_key);
-                final String popupPlayerKey = getString(R.string.popup_player_key);
-
-                final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
-                boolean isExtVideoEnabled = preferences.getBoolean(getString(R.string.use_external_video_player_key), false);
-                boolean isExtAudioEnabled = preferences.getBoolean(getString(R.string.use_external_audio_player_key), false);
-                boolean useOldVideoPlayer = PlayerHelper.isUsingOldPlayer(this);
-
-                PlayQueue playQueue;
-                String playerChoice = choice.playerChoice;
-
-                if (info instanceof StreamInfo) {
-                    if (playerChoice.equals(backgroundPlayerKey) && isExtAudioEnabled) {
-                        NavigationHelper.playOnExternalAudioPlayer(this, (StreamInfo) info);
-
-                    } else if (playerChoice.equals(videoPlayerKey) && isExtVideoEnabled) {
-                        NavigationHelper.playOnExternalVideoPlayer(this, (StreamInfo) info);
-
-                    } else if (playerChoice.equals(videoPlayerKey) && useOldVideoPlayer) {
-                        NavigationHelper.playOnOldVideoPlayer(this, (StreamInfo) info);
-
-                    } else {
-                        playQueue = new SinglePlayQueue((StreamInfo) info);
-
-                        if (playerChoice.equals(videoPlayerKey)) {
-                            NavigationHelper.playOnMainPlayer(this, playQueue);
-                        } else if (playerChoice.equals(backgroundPlayerKey)) {
-                            NavigationHelper.enqueueOnBackgroundPlayer(this, playQueue, true);
-                        } else if (playerChoice.equals(popupPlayerKey)) {
-                            NavigationHelper.enqueueOnPopupPlayer(this, playQueue, true);
-                        }
-                    }
-                }
-
-                if (info instanceof ChannelInfo || info instanceof PlaylistInfo) {
-                    playQueue = info instanceof ChannelInfo ? new ChannelPlayQueue((ChannelInfo) info) : new PlaylistPlayQueue((PlaylistInfo) info);
-
-                    if (playerChoice.equals(videoPlayerKey)) {
-                        NavigationHelper.playOnMainPlayer(this, playQueue);
-                    } else if (playerChoice.equals(backgroundPlayerKey)) {
-                        NavigationHelper.playOnBackgroundPlayer(this, playQueue);
-                    } else if (playerChoice.equals(popupPlayerKey)) {
-                        NavigationHelper.playOnPopupPlayer(this, playQueue);
-                    }
-                }
-            };
-        }
-
-        @Override
-        public void onDestroy() {
-            super.onDestroy();
-            stopForeground(true);
-            if (fetcher != null) fetcher.dispose();
-        }
-
-        private NotificationCompat.Builder createNotification() {
-            return new NotificationCompat.Builder(this, getString(R.string.notification_channel_id))
-                    .setOngoing(true)
-                    .setSmallIcon(R.drawable.ic_newpipe_triangle_white)
-                    .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
-                    .setContentTitle(getString(R.string.preferred_player_fetcher_notification_title))
-                    .setContentText(getString(R.string.preferred_player_fetcher_notification_message));
-        }
-    }
-}
diff --git a/app/src/main/res/drawable-hdpi/ic_info_outline_black_24dp.png b/app/src/main/res/drawable-hdpi/ic_info_outline_black_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..4b5ab06e19d61515cf3a7395db43a81bb30a8203
GIT binary patch
literal 487
zcmV<D0T}*?P)<h;3K|Lk000e1NJLTq001Na001Ni1ONa4O9@aD00055Nkl<Zcmd_q
zF-l`$6vgqMc^Zo`23v74HbPLeuuw$YiAb<e&;bobm<@=dGRqK`F&ahm#SLhafm;N=
zkf&cWmH)3h_uND72|VACx;0&QN*_Ly?wnaQg?!A}_hvBW^|du+vZXYreqL<&lESay
z!e0lL%&V)Lx8%_MaMo3P9`i>S-P=?%O3jv@aJa6HGW<0ceyC!`rEoc~?j{U=`ic|b
z9N*QPsMv*+MQv@1i8kR%)UIh1`=XoCqqIYBOKErvea{GWZ!y>;D~RpT`=%tUi9cM8
zjMJd-5IZXpx*;AQpQG66NVp4e3Hh{Q=T<@);yl@>u@F125<Wt#lU+8`F?s(FLFs83
zLFs83WhX(IWuJw3i2R`An4C&j4e?$rJE+i$$+CpHe#l$dK|7(BCdV)I%wz@4dJ27)
zQJP+2beZ)Txe4#HhB0gy#5*zJGbVI|)4B?}!r)3n6|-)HOGhPzYhm(eTQO$7<4HLD
zR#T0_xq)~d9BElFZQ6pCW4+<5qvlICqW0?dY+WWzd-`KTO1m2J!ITvpw_d$__v+TE
dWs|-i{{WmHAv4QI(>nkF002ovPDHLkV1kFY-~<2w

literal 0
HcmV?d00001

diff --git a/app/src/main/res/drawable-hdpi/ic_info_outline_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_info_outline_white_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..c7b1113cfef22bcec86ead7ae67be12326276cab
GIT binary patch
literal 485
zcmV<B0UG{^P)<h;3K|Lk000e1NJLTq001Na001Ni1ONa4O9@aD00053Nkl<Zcmd_s
zK}sWE5C`CAx5mX^4Q|E5xDiCrg^NfKZz9sTP|yJlM(_gSUuBLV9>W+#V#f>U=9~3v
zy5k#|%`o-bRp5gvNWBjKU}@RX_o(#cOX<;tO*2A$>f4JBeW<IkLOT`eDov`9&i7F6
z3c!;itCqC1ELnAI0H80Q1m%7L26kjZC7G@v;7;BQT>-BBCp2Wv4dAi~>H>ZU-{cI?
zse=}k;97{XqEJ|gdQ)z}NLv+h2nN-m6riYd=e>Y~D%A1;c7!A-*ac%VF|-AqWJ2?3
zQF6~<BZm6mNRXZr(2Jo*uqsH;8hD7I5-bVHqXo<0J%+wOOGsXJFbh8aI24VR2t}hM
zEIWb{mwf?_e+xPV=P|Si2C`%*Hw5d|zsMMLlc7COnvS8M07G+0(1KU6FI1tn5x7Y@
zBlqCVyecH<0M1Manlq&b*ls$teZZ~xMrOf1pf~CG-vM6i$_3Tm_q+oBmrZ_-E&)6{
zv1Zw<S<BX(8UpCazJDM)Mkdvp?bIi`?Z8-FmG<lR7c^zYhMouSK7D%k;M}_Dw2z2{
b{5{Yw40E*CJGBE$00000NkvXXu0mjfPuAE+

literal 0
HcmV?d00001

diff --git a/app/src/main/res/drawable-mdpi/ic_info_outline_black_24dp.png b/app/src/main/res/drawable-mdpi/ic_info_outline_black_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..e0c9fe0eb8457013fbfa6e2efea61fca70bb9303
GIT binary patch
literal 323
zcmV-J0lfZ+P)<h;3K|Lk000e1NJLTq000;O000;W1ONa4N`Cco0003BNkl<ZI1#<U
z!AT=w00z)EIm}d|Xc3ES3xc93UOY@ti%|&JgQBHKumELHTQDY<Z*Twnt070<<F|Fr
zJQ}R53?7{7Y;fd5L_|cyyF+VD+=_V8+tO-no0^N5nfT#Wd^-2PMsFczzBv+~{#a+v
zLL8`cKE%0E#Aqtsw2CwFq!ux1%*Bb~QS>&s5ci5fY}sT-yed|rRg0)~VyRe(RxP5|
ziKSu?+iDTDUGbuL5L2~?+LgFdoQk=|C}Pxj7RQRtyXcJ~MwepHsvL@iJ?s4SCH8$Y
z6AQgYt#Ro~-1uQ)CSvZwj!tLSm1hyxCe}LeCL$stVz6(6)`@$smX==JIoA4R{{X3C
VfQx`Hg^K_H002ovPDHLkV1oM>kN^Mx

literal 0
HcmV?d00001

diff --git a/app/src/main/res/drawable-mdpi/ic_info_outline_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_info_outline_white_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..353e064951788a29a64eef439284fd97e904f374
GIT binary patch
literal 320
zcmV-G0l)r<P)<h;3K|Lk000e1NJLTq000;O000;W1ONa4N`Cco00038Nkl<ZcmciA
zL2BY)6u|K>T_h)IX%8`!xx#?O($dW=BI;pgAmAMoJ&FVmpak^_M&10n8om%>Hp0CB
z>RbH6BfRjxN9M~)<?5=k^eGdX1<i(z+H>&M4Ia$ETJBLQ^<<<3g$He5hLhidW{F&l
zq78;P`5|=ls>YxRGDkGO4)Ha@UK+s{*1}DYDDe@&3c1kJ7>fuhJobWT>>{`#?O7?v
zaJd6ic<Kc&*ha9#s25BzkKhxfr02J8@E$?tfcz$yppr%qyrK3gboA31zuL!Fpq5Ko
z$2W1t->&m6Kxyn*Ci7xy1O7D6yV<~Ad#ZoSbb%oCVPWUuVr%YQDrkfL?gZZ)JBOfu
SH&bZ<0000<MNUMnLSTaQqmeiO

literal 0
HcmV?d00001

diff --git a/app/src/main/res/drawable-xhdpi/ic_info_outline_black_24dp.png b/app/src/main/res/drawable-xhdpi/ic_info_outline_black_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..b706f0d06a9a1e5e2f6606c01e84094ee6a99b42
GIT binary patch
literal 640
zcmV-`0)PF9P)<h;3K|Lk000e1NJLTq001xm001xu1ONa4{R=S+0006<Nkl<ZcmeH|
z&q^Cn6vlsvlZde!NtjSu`vyf3BJn|lX3>o#<ONz1^8nhqwMf8rtJpv`Md(`;gR817
ziruJbp-S^-Gu<2x$joJC?$CnZ?=H`G&v$d~{W3goFG#aYi!Mj>88fEO5na|OlO{3G
z*yIPEVO{WsIjnKnVT>2DMzkql!ApMPMO=L<#3I9oI}LubOO+CNvScYxqQ)LKcQkDr
zB9h}Xp02N~GG)+JIYyNnkc)PDZO<QG;e@Cg3{VRkLV2(9W1bU*c}~$mg<h>nzu*#;
zB8R%~1(<R9rKfj^Ls5UlHF=Ee=<EZBqo)jFfuU5ljj7dGy@uEZ(A4NXA&^adn2wb}
zh7+l85I|c0b5_C10BTY{Cxwq?P3;u6Omiz;mhjP%(k@BZmo80wbfr`!33chx!N-x5
zN+h8yU3&QFODPZ5mkh2buJ9olAe+cwQnT>i4Rl0>e>Eb#WLtxfOV(#vvo;8MrfX8#
zOJwj-6b<u_yCG+7@Q7RUpwnDvmMsl*Kxd=~;H`emGFApzzDa$ZK;|?H4J(6|RENxB
zpe>RC^RW#U^^>`Uk%GqUlp=9>%y-#&$qZ(w=qV2=#%SNueJg~}R_Q4VL}5`+@9~aM
z91c`Iph*TZkfp^?^`Dp^0y)$Ij}vN48)8+LhbiruA|j3sO47|fb;`I*GKou>Ivq)^
z4u=V1QQ;ad;<{u73-W9;3T-}Qiy5qW$_D4g=4Y%kOJdS2(WFC<D@KgCqDO}YB~si2
a9{39-;{s}$p1&6W0000<MNUMnLSTYm?ipPG

literal 0
HcmV?d00001

diff --git a/app/src/main/res/drawable-xhdpi/ic_info_outline_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_info_outline_white_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..c571b2e3e776762bb90733f664f9d66e2c7f321c
GIT binary patch
literal 655
zcmV;A0&x9_P)<h;3K|Lk000e1NJLTq001xm001xu1ONa4{R=S+00073Nkl<ZcmeI#
zK}*|y9LMqBza|xR7io#OO`pL~gi3uN!aR79mOg=v);<8;yeblKyDI(*y@=qm7#2^~
zDvDmzZlIz~F7F+_{GgD8B)<;Ez}M#*`i7(liTW43BEtf8nw-$Z$EV8)O;#zALB%cZ
zfN3_kA<8vhm@*GI?BEl}!zFJLSmq~5by-Rmu=!5E2X-k@AV-!gc?y)-<B@(YR?@&I
zM`&=$3L}IcSE7vuhm0l(*c_of^9c(TJ#4DH^d+qLz&EruA5aN4LkG=`3oN7kz(FP4
z1jlF}i4NfK3(-#T^OEQw?#V?5b`Z}ICr48uo27@?jtWfUBR->22NX4g$Gh;r2I3UU
zC}4AjSPu(ixIwI-i~@=>;)?%*fd#|^BPhd-@r0NU2I`1i6z1DU)PjK~qBKyTf@lN-
zCy2s8fg++640I7Wl<`GYIEcGoz(-^U3JfE>zYypm@_+0U8C+z9*+p(5%4UK1zv(Js
zZ=k^ch-xrUL_9KT9C*VMq7V#ZxJHzW0~N$&*uzfo7172v3S>D)tf9gJQ}~FgQJ{|K
z@irKcxri5LQU~VfAvRG_fjnJAhY3`QO>%*_Wjs2dSVB8ak(i`~wix%~<)U?%MJ3oA
z7ie3kxPZkW+6y&o6w%94r-ydHP_ma_Nr*Gbj78j570v<efRUuH?-nlo9@(ct5r<)h
zaVS!u!4v(q7)tj6vcx?}-Lh!%36*0Tk2pOx88`n3e9t;pM7d;5?po7;EW<oC8nn2>
p!{d$?4XPC6k!Bt+*lWOGzX87wDYF(rDzN|n002ovPDHLkV1ir08p{9x

literal 0
HcmV?d00001

diff --git a/app/src/main/res/drawable-xxhdpi/ic_info_outline_black_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_info_outline_black_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..3847a9fe74774d3593dd694cff48ccca13cdec5a
GIT binary patch
literal 940
zcmV;d15^BoP)<h;3K|Lk000e1NJLTq002k;002k`1ONa4|Kxkj000AXNkl<ZcmeI$
zUuzUs7{~E%i0)QrCy}t*6>mdcfcOtJM6uO{+z8D@UxkKMBq1+Buz@6?P#P0jG1VJo
zr4$sRhK5k2Z=fXRN~6nW@y^{1KD~XI=}gYdoFjX&pWp3sm><rZJ;%_~wR(CyD$KCV
z2HP}f)26{T8!R)!6%O+imASzhZ6qcwUQ^{;oV&;~_7KB#s4<2!m-q`wku@%0-7$Vg
zGUNeAvFJxWAsN$T0xR;|i+IEi51FLGFhk_XF~l$xCRyP_#EN-xWHi7k5=w)4P7&uc
z3+y7HJf}bgCH_GIc}Eow6CO8tj|B3D5-AOY>a@9yM-m0@&<R!YNg*G4S^sjJG)}OI
z=<tFZiQPqXc#2P2gFHiYm`lFVMTej1CyN6tB0Bs)0>}6isAEB(Qj;>qRst`p9~=6q
zAu7LO=u+TQ_K7Dd@dg8*_ZUX>5!&WBSSti4^<9Bi7`TY2+y<+KU=~psWnX%OzQeO#
z$Y%%reeR=-{wJ-1^+Iq9eT6F#>jwG=^_&zcppV__#9BjN7F^M%z)NCy=&SoFTsf<r
z@|i<Ks-Ul5?(|VtPr6K`88!A0mmaAnO%rKZjZNZGRXyoGkv7y=1((Lvlh%o}t;U8i
zB`T&y)S4|KHPqOU(?UhHrcNZi>2ppC<<**2_ZI5@SJo9Db@pv9Dwel>@Q2Y|A^pR+
zXm)h0I4$&8t(hXy6*cz3S)t(J`aO{jqc{F(SB1>4AMjd@E;uWs|KhZ2{;};ky2AQ2
z)rxDxD$`NJH=PukQuA$!?4zc}-&3$&Xn>Du{t5dULsafqFEod!oWp?rpGSuiRtueB
z&+LQNE+8tK3|cF6gtuz;3+FNP08y#Yj|~U-15sJR*io8@$}eQs#}cB_phN-_NT5>I
zKj|$a=v*bC1q7WMgQRsN@Unzi63g)%L1&Ybq;ZC~2s(dqkQ990An0_M#V3gY=Ga5f
z`5TXvN})=^4!0;^!e^R~NT^Pc418W7q3m*(v-A<Ak8|A9J5{|bkBoB6BmbK^kEk-v
z2u1SbDKf%1RUT81Sn(4Fv0{QIk}(agVo{mjGL-qk5+$q~;}w!3tBm5zC{O7ihH3MJ
z^Eg-HIxlG<G5O3Y*C_H89pW<6+-IFF>a=K4XNz?fnc_RXp{J*(OZ^8ac7(2N>$@cY
O0000<MNUMnLSTaLVzg%f

literal 0
HcmV?d00001

diff --git a/app/src/main/res/drawable-xxhdpi/ic_info_outline_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_info_outline_white_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..c41a5fcffa8c4dc3684252fbfd61623837e19d50
GIT binary patch
literal 953
zcmV;q14jIbP)<h;3K|Lk000e1NJLTq002k;002k`1ONa4|Kxkj000AkNkl<ZcmeI&
z-%C_!9LMn|ta0niXvoYO-HLy}(l08pXtxHu3D%4Lijq@=;-3(-f(i=Dn!|47)=e@J
zLBUj#$P)VxEMs1!HH<@d&6%P1diUkwcz(<|&jVh}>+=u1!Si^=c~o6pU56D8MW!jS
z$u@O7JnC$-Nr`E0Z~~QViq1F4UDojk)8rj4KiUtv${KCrYEfp?UeGn(lf*h#%m<z3
zZ_;?oDU(6B_)1z0#?1uvvdF=9dBOxmh8Q5TzX66QGQkR;IoKSTv_XAT@T)V&IaJ8b
zGtVA=ugIneD)29$`-F>wiZO?K>;SqC6p{w@`EooS#EOw+c}UBbluHuSO9kD3{Dexd
zGgQ&NCewM)0=iXlsD$fh4c%;~LATKTP7f-@j<SUA*G_^?^A$Zu8JM2bU@(5r3LsYL
zF%r~684!QQ4Z5a3%8}0wBJx?P0%9~?(0ha@Co4se>@01>+c-g20r3E3BuF*`h>_@^
zHN+<z<3Txg5vx%_gR~JY%2<%>KB7e-Jm@Z>j$<V#%O2uRc+fgx4rOTzh&N$D4j$s1
zwV;cLZyXN}Dk64K)^>y%;(Bn<G~x-$;+`U=f`dwk39CUa;!$wWCZcFHXbiCt9JGxX
zLdgsrd)Y8zD>$f*7_b_YN7RCYJVeH7P%ol+c!LiAkL*xA)X9%M!t}A%e=*t&auG}M
zUL7k|gPtKKgM)4$K3fdZU#`Cd2c5t}oVOJe{qaNg4l!>nXc19Cg$22YJsc}RIU0!D
zQ6KVKh<jFoCJ`R_@E}DQu|w8)P#<3q&rwl9qkwp5JZKgHmx6<2>xdR-j0Rnxtv}Fl
zg03K-O24t7lYB&c=W=+E>@fn$hQ5wD$_oT6qv8ggqJe-vjQr`djDR|Y=pflR=t-%+
z(kr36+3A;_^XSU-C(b#^3v@H6PJ=SMLRaN%qMQqSME8<o@q=VJKA>wcL$0HkK4xj7
z`v)iS)q*bxcDYYB<~wVOFW}3`r@4H|@fyE97P!cfkP~%@MH=|M#7TQSm0^y9)p&}_
z7{lc0-Cv$z#&CH?jf4HhF*6r<<1|RC&P|h7oP+#Da^G2|VEz(#l(!^NVZ`1w`3S4D
zh|A+Sm+k)}L4iBGp-Gr;RJbh%++L9EIM<ot5gTk#qq)BtTWqkzBtP>5D%liv*A40h
bb%Xu~a~|hNXxfgr00000NkvXXu0mjfV)nVh

literal 0
HcmV?d00001

diff --git a/app/src/main/res/drawable-xxxhdpi/ic_info_outline_black_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_info_outline_black_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..c1e2a03a4bc540419ce1165d5dedd8d5345fdec2
GIT binary patch
literal 1256
zcmV<E1Q+{>P)<h;3K|Lk000e1NJLTq003YB003YJ1ONa4NRhv@000E9Nkl<ZcmeI&
z%}-QU7{~FiOk$iF22A8d5@W;;R&=9rXJX@~RYQHvL=BB5{Rey@gNmXiZZ*0iAP8ww
zBPF<Xfo~f_O4BU~Z2>W$LQv#I8j8T_{yf~=m$~;IXzu5?eh%l+bI*O5LnIQ3L?S-g
zNEKIT<0XBJGshx}%rQ<MFKFcoRg|(K<&&X>L6n2^)65BytPpur(aAq3mzkx5L*!vp
z0a@Ola>x)hq%a~$J)clM<Rf(?2-z9lqI}FS)r4j%&rt!Si!FrUM`lm~Wr{NdD$dUi
z7DESh9Ag({#EB6jP8qv7&Q&@Xv8``m9Rb<MA1KQ#@rv`Lu~WfCx=~o?H%bV=Hmo<y
zPuwPr8x`DP%5uCxzQSia8MXLh6V#EyivsGIv>5drmH23z#q<|xU<0`*qKPGo7Si~n
z%wqBU&0hSlj{%E?RDuuU7MJcXB=Jj%b`&x_e(Xp;ExUAT@Y|(jm(qjWZ(B;_Uor&Y
z6!R#Nv*chaGsx+GPf(5^TbQOC&z>U}Plh0!MlPf-JUW9CsUc{WQ6klNkmN0L=W$Hb
zI`=E``6_{H*O2>uGL!}iknh%)aH)U^vHJHyC=I|j;!5~HKCWcN1R5Z;2B2BgU%-W!
zczBp#L#PcDi)Yo><l$HqN=qGt+5p@XBOJi7PVu~-3cZ0s@qh3Lhw{Z|s@o8H18`Rx
z;WG&w$%vQ5G$w3EX*r4`En3+tOzF{P(ufn{HgX;_<YxXS4s1keNn^?mF_&WZTj($*
zz1L=Q5L;KYk`By~8+t9a+T<<FpzGRfnz8j#D>;Taa!Y@Ptv;<}7l4r)8NeQGlwNF&
zYb9ky8`z|cGKQ@=tt4)=frR*F&DNq;5;NLBOdDlk)i<!(mQYeIq5t_sEVt3!t8E*7
zp_Lpr*nqr|J;he5R&v#712?o$?t6HcGupsoZIrD0$LSHH4UD?~GEs`sQemutonBsO
zpkFJxXsm%+@k;6GvtGBc27dSUdGmz$tWsg5fl4vPVH`;^s}<fc(!f1!gc;&E)FDoh
z6olTudhz?*LmWGV(o!FK1GmHo-{DvuLt619MWHrO%Cz|1ehn_vhzT@>+CZzQKZh$R
zK8n3)UuX^N7uDk=aj8xWGC(Sn1_~Jx)mdCiFf4{?52b-lQTv8C9#o@5E)leAD3OzR
z)Fn^Gaf%@QAdedG1kbj}b8XCXgrFSb3rcL@n*sbhFEP*Qfd2Kr_;5}_cz_aF;&K3M
ze+ebhM9$XHgOZ`06n-hB6D318Yw<w|gD4pW*oPnXGlY_%pCWvc=AFf9-DZl(MJa8l
zW%HJDd{k-Cf?|rB6yn8tZZT~!>ImEMS(?`<%O>vfHEvXL&vNpLe#!|zDLp9b&_k9T
z*x5;~c-Pf0-68_APCn*}yr+}vWZ1(d62yp+WD|SHaD&H;+SWI+mO!0l8Wm6`sU`&F
zbfE&s6E+i?YKBohW{8u7EWu?ypnS+US>hOx&jq=;y2>EuNMckT2YAG1l*`QUkZ)PT
z3X$L_jr@gjkUknXOq>;|goD)5%rkl!W0nOLm}QJ!o^qco2Ph^Ii9{k1-~0zqnGDmx
SqDLYC0000<MNUMnLSTX%6+fW>

literal 0
HcmV?d00001

diff --git a/app/src/main/res/drawable-xxxhdpi/ic_info_outline_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_info_outline_white_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..3a82cab3b4f2cfe77333cee6121d867353753d5e
GIT binary patch
literal 1279
zcmV<b1OWSqP)<h;3K|Lk000e1NJLTq003YB003YJ1ONa4NRhv@000EWNkl<ZcmeI(
z$!ip89Eb7OG)THTi(nQ5BF0G^my6;}aPTq{CF4q?k|BcsfJ^A8aRsl6-hvv9%%JFm
zc=Zssi-d`I6*6ON6XHr-(uomA?Rw_?d%N0Nx~g7f`t$t<>XA;<CGV?BN=iyfN`k{Y
zS~<ui?lQ~-AIXv9BNGgBhh7fSN<AvbDS}xADK3z~jS+g-O7dF?D5I5rKH$|1eXOU<
zY(N!h#wf-p9aNeLNOFXC1mO)`B%%&z=NUm7r!BgGMcgI~11yXpU>DPbB};p_0dfAo
z$vAy<v6&S#5GO{AI1Q|13y0|ADNZg>9#+6S9#ELYJ@(Lqa#%C_802gIqArYp#f(wN
zJ5D-2x}I^0EQMtFA?SeRyu{vHx_o|<S8;?%>^)~`kO7MeJbsRD=Aw#N4d<{5Bs2vT
z(7+gW9<dq~z}D~>I~nSN2#E6lJC{kK0$L^4urow?@d3Y+FGmL|;O)mE-^F4Bc9HL2
zQm7ENoloT3SxmqprfnYoS5!#bXp=BSqyK>0=yIe`A#Mj2x&gld?d0n~g}ejgYx5J3
z<QcllDA&^|*ZULQI0^3ohtWME8A(7D8Fc%-22}ADDaUG5Bms(_u#jF;;VmGIt{W9u
zfT9Q8UM~SL#*p4JH`0JwvPe%Tb05%(t_u}ufZ{m17WV=DNbjhOJfNB^(p9$s6?{NC
ziHbZxaT@7833mZ0B#S1Lfh|F|$z8w&q<bhs8$vqkE+B)n$5=ob>2Egy^UyUJ3s{D(
z);XXRX&hy6FOb$b2OLD|GaAs3)ae{>38~9yz)_?g=YYFNn~esfkZw5#3?r>T`I=7o
z+A5@n&H)oh4MqdzBfWAC_=prY8jwJmaSq5K#f%2TkiLBX0pHn2D2X)lKlmdaMq2s3
zeU08h+F~>yg>=(7pcm<o(STz}=ZpF=XCUA@Qri2^>8C~mULv(P2h^i$HWskl&kK!W
z1ZkhKfKETJl!_jtL1O{;k-FUlY(=tYHWIKD-3E67NoJ5v83{OpG)>%HfT9m6OI73n
zbC^cDf^r+M9^H}115Tj(#eF~-qezp~L>f@f6jFv+?gJDZ=*~qN(2H(2%1b~cZ;&k3
zL>90X-2_Q*0g5hkkEx6#pqf#1X_VK11mozgMH0}DZj8A107V=5_M<}HVe)PBd(>b6
zoyB%ki2Dr--3^rAfQ4kyePSajq;2Lix=9xJ4^Xs&O~Q_l{`EhTudUbvPZ!B&aUg`x
zzD2%ssA2=k8N$vrDp3KgnttpIGQ0QyMI9OJJZ23lfURW|J0sKtb?mZ<=h(66p%zud
z>bZoyXEX+R@O5c{1jurnYLt)7;RI9Id&-iaj~+Mi1PVr+=0}fjTW6S}kP#ZgIQ(7D
z5MMJynq@Bjr=gSke9a&=VI99OrxzzL=;tUYRxzIhF=8Z{&ni+J<2o;Ka+cZQUVzxi
z6k(a9Es85BjSLWm8!U+K5>OlC1Zk9QQD4JKaDdkYVS+SqGZ*11*vk`&kzqGU(^nB&
zxXOFHn&t{WGwWNq44PmQXZZ&=hUsR5_|TXQ5UXPyo%C>vhrD8jFMMH!S3Kk<=SkB-
pEh@+<Os^DRa;1P$Kq;UU@E-(*#@c1Rm*W5c002ovPDHLkV1iCcH*Wv{

literal 0
HcmV?d00001

diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml
index 794365a3d..31eda4fbc 100644
--- a/app/src/main/res/values/attrs.xml
+++ b/app/src/main/res/values/attrs.xml
@@ -3,6 +3,7 @@
     <!--TODO: preffix these with "ic_"-->
     <attr name="thumbs_up" format="reference"/>
     <attr name="thumbs_down" format="reference"/>
+    <attr name="info" format="reference"/>
     <attr name="audio" format="reference"/>
     <attr name="download" format="reference"/>
     <attr name="share" format="reference"/>
diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml
index 372b917e0..8f33f9297 100644
--- a/app/src/main/res/values/settings_keys.xml
+++ b/app/src/main/res/values/settings_keys.xml
@@ -155,6 +155,7 @@
     <string name="preferred_player_default" translatable="false">@string/always_ask_player_key</string>
     <string name="preferred_player_last_selected_key" translatable="false">preferred_player_last_selected</string>
 
+    <string name="info_screen_key" translatable="false">info_screen</string>
     <string name="video_player_key" translatable="false">video_player</string>
     <string name="background_player_key" translatable="false">background_player</string>
     <string name="popup_player_key" translatable="false">popup_player</string>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index ea8f0fce8..0e9f6e7ac 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -30,6 +30,7 @@
     <string name="channel_unsubscribed">Channel unsubscribed</string>
     <string name="subscription_change_failed">Unable to change subscription</string>
     <string name="subscription_update_failed">Unable to update subscription</string>
+    <string name="info_screen">Info Screen</string>
 
     <string name="tab_main">Main</string>
     <string name="tab_subscriptions">Subscriptions</string>
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index b16958ae6..dcf8f9268 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -18,6 +18,7 @@
 
         <item name="thumbs_up">@drawable/ic_thumb_up_black_24dp</item>
         <item name="thumbs_down">@drawable/ic_thumb_down_black_24dp</item>
+        <item name="info">@drawable/ic_info_outline_black_24dp</item>
         <item name="audio">@drawable/ic_headset_black_24dp</item>
         <item name="clear_history">@drawable/ic_delete_sweep_white_24dp</item>
         <item name="download">@drawable/ic_file_download_black_24dp</item>
@@ -69,6 +70,7 @@
         <item name="thumbs_up">@drawable/ic_thumb_up_white_24dp</item>
         <item name="thumbs_down">@drawable/ic_thumb_down_white_24dp</item>
         <item name="audio">@drawable/ic_headset_white_24dp</item>
+        <item name="info">@drawable/ic_info_outline_white_24dp</item>
         <item name="clear_history">@drawable/ic_delete_sweep_black_24dp</item>
         <item name="download">@drawable/ic_file_download_white_24dp</item>
         <item name="share">@drawable/ic_share_white_24dp</item>