Android Open Source - ponyville-live-android Debug App Container






From Project

Back to project page ponyville-live-android.

License

The source code is released under:

Apache License

If you think the Android project ponyville-live-android listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.ponyvillelive.app.ui;
/*from  w  ww  .  j  a  v a 2  s .  co m*/
import android.animation.ValueAnimator;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Build;
import android.support.v4.widget.DrawerLayout;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

import com.jakewharton.madge.MadgeFrameLayout;
import com.jakewharton.scalpel.ScalpelFrameLayout;
import com.ponyvillelive.app.BuildConfig;
import com.ponyvillelive.app.PvlApp;
import com.ponyvillelive.app.R;
import com.ponyvillelive.app.prefs.AnimationSpeed;
import com.ponyvillelive.app.prefs.ApiEndpoint;
import com.ponyvillelive.app.prefs.BooleanPreference;
import com.ponyvillelive.app.prefs.Endpoint;
import com.ponyvillelive.app.prefs.Endpoints;
import com.ponyvillelive.app.prefs.IntPreference;
import com.ponyvillelive.app.prefs.NetworkProxy;
import com.ponyvillelive.app.prefs.PicassoDebugging;
import com.ponyvillelive.app.prefs.PixelGridEnabled;
import com.ponyvillelive.app.prefs.PixelRatioEnabled;
import com.ponyvillelive.app.prefs.ScalpelEnabled;
import com.ponyvillelive.app.prefs.ScalpelWireframeEnabled;
import com.ponyvillelive.app.prefs.SeenDebugDrawer;
import com.ponyvillelive.app.prefs.StringPreference;
import com.ponyvillelive.app.util.Strings;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.picasso.Picasso;
import com.squareup.picasso.StatsSnapshot;

import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.SocketAddress;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;

import javax.inject.Inject;
import javax.inject.Singleton;

import butterknife.ButterKnife;
import butterknife.InjectView;
import butterknife.OnClick;
import retrofit.MockRestAdapter;
import retrofit.RestAdapter;
import timber.log.Timber;

import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import static java.net.Proxy.Type.HTTP;
import static retrofit.RestAdapter.LogLevel;

/**
 * Created by berwyn on 16/08/14.
 */
@Singleton
public class DebugAppContainer implements AppContainer {

    private static final DateFormat DATE_DISPLAY_FORMAT = new SimpleDateFormat("yyyy-MM-dd hh:mm a");

    private PvlApp   app;
    private Activity activity;
    private Context  drawerContext;

    private final OkHttpClient      client;
    private final Picasso           picasso;
    private final StringPreference  networkEndpoint;
    private final StringPreference  networkProxy;
    private final IntPreference     animationSpeed;
    private final BooleanPreference picassoDebugging;
    private final BooleanPreference pixelGridEnabled;
    private final BooleanPreference pixelRatioEnabled;
    private final BooleanPreference scalpelEnabled;
    private final BooleanPreference scalpelWireframeEnabled;
    private final BooleanPreference seenDebugDrawer;
    private final RestAdapter       restAdapter;
    private final MockRestAdapter   mockRestAdapter;

    @InjectView(R.id.debug_drawer_layout)
    DrawerLayout drawerLayout;
    @InjectView(R.id.debug_content)
    ViewGroup    content;

    @InjectView(R.id.madge_container)
    MadgeFrameLayout   madgeFrameLayout;
    @InjectView(R.id.scalpel_container)
    ScalpelFrameLayout scalpelFrameLayout;

    @InjectView(R.id.debug_network_endpoint)
    Spinner endpointView;
    @InjectView(R.id.debug_network_endpoint_edit)
    View    endpointEditView;
    @InjectView(R.id.debug_network_delay)
    Spinner networkDelayView;
    @InjectView(R.id.debug_network_variance)
    Spinner networkVarianceView;
    @InjectView(R.id.debug_network_error)
    Spinner networkErrorView;
    @InjectView(R.id.debug_network_proxy)
    Spinner networkProxyView;
    @InjectView(R.id.debug_network_logging)
    Spinner networkLoggingView;

    @InjectView(R.id.debug_ui_animation_speed)
    Spinner uiAnimationSpeedView;
    @InjectView(R.id.debug_ui_pixel_grid)
    Switch  uiPixelGridView;
    @InjectView(R.id.debug_ui_pixel_ratio)
    Switch  uiPixelRatioView;
    @InjectView(R.id.debug_ui_scalpel)
    Switch  uiScalpelView;
    @InjectView(R.id.debug_ui_scalpel_wireframe)
    Switch  uiScalpelWireframeView;

    @InjectView(R.id.debug_build_name)
    TextView buildNameView;
    @InjectView(R.id.debug_build_code)
    TextView buildCodeView;
    @InjectView(R.id.debug_build_sha)
    TextView buildShaView;
    @InjectView(R.id.debug_build_date)
    TextView buildDateView;

    @InjectView(R.id.debug_device_make)
    TextView deviceMakeView;
    @InjectView(R.id.debug_device_model)
    TextView deviceModelView;
    @InjectView(R.id.debug_device_resolution)
    TextView deviceResolutionView;
    @InjectView(R.id.debug_device_density)
    TextView deviceDensityView;
    @InjectView(R.id.debug_device_release)
    TextView deviceReleaseView;
    @InjectView(R.id.debug_device_api)
    TextView deviceApiView;

    @InjectView(R.id.debug_picasso_indicators)
    Switch   picassoIndicatorView;
    @InjectView(R.id.debug_picasso_cache_size)
    TextView picassoCacheSizeView;
    @InjectView(R.id.debug_picasso_cache_hit)
    TextView picassoCacheHitView;
    @InjectView(R.id.debug_picasso_cache_miss)
    TextView picassoCacheMissView;
    @InjectView(R.id.debug_picasso_decoded)
    TextView picassoDecodedView;
    @InjectView(R.id.debug_picasso_decoded_total)
    TextView picassoDecodedTotalView;
    @InjectView(R.id.debug_picasso_decoded_avg)
    TextView picassoDecodedAvgView;
    @InjectView(R.id.debug_picasso_transformed)
    TextView picassoTransformedView;
    @InjectView(R.id.debug_picasso_transformed_total)
    TextView picassoTransformedTotalView;
    @InjectView(R.id.debug_picasso_transformed_avg)
    TextView picassoTransformedAvgView;

    @Inject
    public DebugAppContainer(OkHttpClient client,
                             Picasso picasso,
                             @ApiEndpoint StringPreference networkEndpoint,
                             @NetworkProxy StringPreference networkProxy,
                             @AnimationSpeed IntPreference animationSpeed,
                             @PicassoDebugging BooleanPreference picassoDebugging,
                             @PixelGridEnabled BooleanPreference pixelGridEnabled,
                             @PixelRatioEnabled BooleanPreference pixelRatioEnabled,
                             @ScalpelEnabled BooleanPreference scalpelEnabled,
                             @ScalpelWireframeEnabled BooleanPreference scalpelWireframeEnabled,
                             @SeenDebugDrawer BooleanPreference seenDebugDrawer,
                             RestAdapter restAdapter,
                             MockRestAdapter mockRestAdapter) {
        this.client = client;
        this.picasso = picasso;
        this.networkEndpoint = networkEndpoint;
        this.scalpelEnabled = scalpelEnabled;
        this.scalpelWireframeEnabled = scalpelWireframeEnabled;
        this.seenDebugDrawer = seenDebugDrawer;
        this.networkProxy = networkProxy;
        this.animationSpeed = animationSpeed;
        this.picassoDebugging = picassoDebugging;
        this.pixelGridEnabled = pixelGridEnabled;
        this.pixelRatioEnabled = pixelRatioEnabled;
        this.restAdapter = restAdapter;
        this.mockRestAdapter = mockRestAdapter;
    }

    @Override
    public ViewGroup get(Activity activity, PvlApp app) {
        this.app = app;
        this.activity = activity;
        this.drawerContext = activity;

        Timber.d("Starting DebugAppContainer#get");
        long start = System.nanoTime();

        activity.setContentView(R.layout.debug_activity_frame);
        long diff = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
        Timber.d("Took %sms to set content view", diff);

        ViewGroup drawer = (ViewGroup) activity.findViewById(R.id.debug_drawer);
        LayoutInflater.from(drawerContext).inflate(R.layout.debug_drawer_content, drawer);
        diff = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
        Timber.d("Took %sms to inflate drawer", diff);

        ButterKnife.inject(this, activity);

        diff = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
        Timber.d("Took %sms to inject DebugAppContainer views", diff);

        drawerLayout.setDrawerShadow(R.drawable.debug_drawer_shadow, Gravity.END);
        drawerLayout.setDrawerListener(new DrawerLayout.SimpleDrawerListener() {
            @Override
            public void onDrawerOpened(View drawerView) {
                refreshPicassoStats();
            }
        });

        // If you have not seen the debug drawer before, show it with a message
        if (!seenDebugDrawer.get()) {
            drawerLayout.postDelayed(() -> {
                drawerLayout.openDrawer(Gravity.END);
                Toast.makeText(activity, R.string.debug_drawer_welcome, Toast.LENGTH_LONG).show();
            }, 1000);
            seenDebugDrawer.set(true);
        }

        setupNetworkSection();
        diff = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
        Timber.d("Took %sms to setup network section", diff);
        setupUserInterfaceSection();
        diff = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
        Timber.d("Took %sms to setup ui section", diff);
        setupBuildSection();
        diff = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
        Timber.d("Took %sms to setup build section", diff);
        setupDeviceSection();
        diff = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
        Timber.d("Took %sms to setup device section", diff);
        setupPicassoSection();
        diff = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
        Timber.d("Took %sms to setup picasso section", diff);

        return content;
    }

    private void setupNetworkSection() {
        final Endpoints currentEndpoint = Endpoints.from(networkEndpoint.get());
        final ServerEndpointAdapter endpointAdapter = new ServerEndpointAdapter(drawerContext);
        endpointView.setAdapter(endpointAdapter);
        endpointView.setSelection(currentEndpoint.ordinal());
        endpointView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
                Endpoints selected = endpointAdapter.getItem(position);
                if (selected != currentEndpoint) {
                    if (selected == Endpoints.CUSTOM) {
                        Timber.d("Custom network endpoint selected. Prompting for URL.");
                        showCustomEndpointDialog(currentEndpoint.ordinal(), "http://");
                    } else {
                        setEndpointAndRelaunch(selected.url);
                    }
                } else {
                    Timber.d("Ignoring re-selection of network endpoint %s", selected);
                }
            }

            @Override public void onNothingSelected(AdapterView<?> adapterView) {
            }
        });

        final NetworkDelayAdapter delayAdapter = new NetworkDelayAdapter(drawerContext);
        networkDelayView.setAdapter(delayAdapter);
        networkDelayView.setSelection(
                NetworkDelayAdapter.getPositionForValue(mockRestAdapter.getDelay()));
        networkDelayView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
                long selected = delayAdapter.getItem(position);
                if (selected != mockRestAdapter.getDelay()) {
                    Timber.d("Setting network delay to %sms", selected);
                    mockRestAdapter.setDelay(selected);
                } else {
                    Timber.d("Ignoring re-selection of network delay %sms", selected);
                }
            }

            @Override public void onNothingSelected(AdapterView<?> adapterView) {
            }
        });

        final NetworkVarianceAdapter varianceAdapter = new NetworkVarianceAdapter(drawerContext);
        networkVarianceView.setAdapter(varianceAdapter);
        networkVarianceView.setSelection(
                NetworkVarianceAdapter.getPositionForValue(mockRestAdapter.getVariancePercentage()));
        networkVarianceView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
                int selected = varianceAdapter.getItem(position);
                if (selected != mockRestAdapter.getVariancePercentage()) {
                    Timber.d("Setting network variance to %s%%", selected);
                    mockRestAdapter.setVariancePercentage(selected);
                } else {
                    Timber.d("Ignoring re-selection of network variance %s%%", selected);
                }
            }

            @Override public void onNothingSelected(AdapterView<?> adapterView) {
            }
        });

        final NetworkErrorAdapter errorAdapter = new NetworkErrorAdapter(drawerContext);
        networkErrorView.setAdapter(errorAdapter);
        networkErrorView.setSelection(
                NetworkErrorAdapter.getPositionForValue(mockRestAdapter.getErrorPercentage()));
        networkErrorView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
                int selected = errorAdapter.getItem(position);
                if (selected != mockRestAdapter.getErrorPercentage()) {
                    Timber.d("Setting network error to %s%%", selected);
                    mockRestAdapter.setErrorPercentage(selected);
                } else {
                    Timber.d("Ignoring re-selection of network error %s%%", selected);
                }
            }

            @Override public void onNothingSelected(AdapterView<?> adapterView) {
            }
        });

        int currentProxyPosition = networkProxy.isSet() ? ProxyAdapter.PROXY : ProxyAdapter.NONE;
        final ProxyAdapter proxyAdapter = new ProxyAdapter(activity, networkProxy);
        networkProxyView.setAdapter(proxyAdapter);
        networkProxyView.setSelection(currentProxyPosition);
        networkProxyView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
                if (position == ProxyAdapter.NONE) {
                    Timber.d("Clearing network proxy");
                    networkProxy.delete();
                    client.setProxy(null);
                } else if (networkProxy.isSet() && position == ProxyAdapter.PROXY) {
                    Timber.d("Ignoring re-selection of network proxy %s", networkProxy.get());
                } else {
                    Timber.d("New network proxy selected. Prompting for host.");
                    showNewNetworkProxyDialog(proxyAdapter);
                }
            }

            @Override public void onNothingSelected(AdapterView<?> adapterView) {
            }
        });

        // Only show the endpoint editor when a custom endpoint is in use.
        endpointEditView.setVisibility(currentEndpoint == Endpoints.CUSTOM ? VISIBLE : GONE);

        if (currentEndpoint == Endpoints.MOCK_MODE) {
            // Disable network proxy if we are in mock mode.
            networkProxyView.setEnabled(false);
            networkLoggingView.setEnabled(false);
        } else {
            // Disable network controls if we are not in mock mode.
            networkDelayView.setEnabled(false);
            networkVarianceView.setEnabled(false);
            networkErrorView.setEnabled(false);
        }

        // We use the JSON rest adapter as the source of truth for the log level.
        final EnumAdapter<LogLevel> loggingAdapter = new EnumAdapter<LogLevel>(activity, LogLevel.class);
        networkLoggingView.setAdapter(loggingAdapter);
        networkLoggingView.setSelection(restAdapter.getLogLevel().ordinal());
        networkLoggingView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
                RestAdapter.LogLevel selected = loggingAdapter.getItem(position);
                if (selected != restAdapter.getLogLevel()) {
                    Timber.d("Setting logging level to %s", selected);
                    restAdapter.setLogLevel(selected);
                } else {
                    Timber.d("Ignoring re-selection of logging level " + selected);
                }
            }

            @Override
            public void onNothingSelected(AdapterView<?> adapterView) {
            }
        });
    }

    @OnClick(R.id.debug_network_endpoint_edit)
    void onEditEndpointClicked() {
        Timber.d("Prompting to edit custom endpoint URL.");
        // Pass in the currently selected position since we are merely editing.
        showCustomEndpointDialog(endpointView.getSelectedItemPosition(), networkEndpoint.get());
    }

    private void setupUserInterfaceSection() {
        final AnimationSpeedAdapter speedAdapter = new AnimationSpeedAdapter(activity);
        uiAnimationSpeedView.setAdapter(speedAdapter);
        final int animationSpeedValue = animationSpeed.get();
        uiAnimationSpeedView.setSelection(
                AnimationSpeedAdapter.getPositionForValue(animationSpeedValue));
        uiAnimationSpeedView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
                int selected = speedAdapter.getItem(position);
                if (selected != animationSpeed.get()) {
                    Timber.d("Setting animation speed to %sx", selected);
                    animationSpeed.set(selected);
                    applyAnimationSpeed(selected);
                } else {
                    Timber.d("Ignoring re-selection of animation speed %sx", selected);
                }
            }

            @Override public void onNothingSelected(AdapterView<?> adapterView) {
            }
        });
        // Ensure the animation speed value is always applied across app restarts.
        content.post(() -> applyAnimationSpeed(animationSpeedValue));

        boolean gridEnabled = pixelGridEnabled.get();
        madgeFrameLayout.setOverlayEnabled(gridEnabled);
        uiPixelGridView.setChecked(gridEnabled);
        uiPixelRatioView.setEnabled(gridEnabled);
        uiPixelGridView.setOnCheckedChangeListener((buttonView, isChecked) -> {
            Timber.d("Setting pixel grid overlay enabled to " + isChecked);
            pixelGridEnabled.set(isChecked);
            madgeFrameLayout.setOverlayEnabled(isChecked);
            uiPixelRatioView.setEnabled(isChecked);
        });

        boolean ratioEnabled = pixelRatioEnabled.get();
        madgeFrameLayout.setOverlayRatioEnabled(ratioEnabled);
        uiPixelRatioView.setChecked(ratioEnabled);
        uiPixelRatioView.setOnCheckedChangeListener((buttonView, isChecked) -> {
            Timber.d("Setting pixel scale overlay enabled to " + isChecked);
            pixelRatioEnabled.set(isChecked);
            madgeFrameLayout.setOverlayRatioEnabled(isChecked);
        });

        boolean scalpel = scalpelEnabled.get();
        scalpelFrameLayout.setLayerInteractionEnabled(scalpel);
        uiScalpelView.setChecked(scalpel);
        uiScalpelWireframeView.setEnabled(scalpel);
        uiScalpelView.setOnCheckedChangeListener((buttonView, isChecked) -> {
            Timber.d("Setting scalpel interaction enabled to " + isChecked);
            scalpelEnabled.set(isChecked);
            scalpelFrameLayout.setLayerInteractionEnabled(isChecked);
            uiScalpelWireframeView.setEnabled(isChecked);
        });

        boolean wireframe = scalpelWireframeEnabled.get();
        scalpelFrameLayout.setDrawViews(!wireframe);
        uiScalpelWireframeView.setChecked(wireframe);
        uiScalpelWireframeView.setOnCheckedChangeListener((buttonView, isChecked) -> {
            Timber.d("Setting scalpel wireframe enabled to " + isChecked);
            scalpelWireframeEnabled.set(isChecked);
            scalpelFrameLayout.setDrawViews(!isChecked);
        });
    }

    private void setupBuildSection() {
        buildNameView.setText(BuildConfig.VERSION_NAME);
        buildCodeView.setText(String.valueOf(BuildConfig.VERSION_CODE));
        buildShaView.setText(BuildConfig.GIT_SHA);

        try {
            // Parse ISO8601-format time into local time.
            DateFormat inFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");
            inFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
            Date buildTime = inFormat.parse(BuildConfig.BUILD_TIME);
            buildDateView.setText(DATE_DISPLAY_FORMAT.format(buildTime));
        } catch (ParseException e) {
            throw new RuntimeException("Unable to decode build time: " + BuildConfig.BUILD_TIME, e);
        }
    }

    private void setupDeviceSection() {
        DisplayMetrics displayMetrics = activity.getResources().getDisplayMetrics();
        String densityBucket = getDensityString(displayMetrics);
        deviceMakeView.setText(Strings.truncateAt(Build.MANUFACTURER, 20));
        deviceModelView.setText(Strings.truncateAt(Build.MODEL, 20));
        deviceResolutionView.setText(displayMetrics.heightPixels + "x" + displayMetrics.widthPixels);
        deviceDensityView.setText(displayMetrics.densityDpi + "dpi (" + densityBucket + ")");
        deviceReleaseView.setText(Build.VERSION.RELEASE);
        deviceApiView.setText(String.valueOf(Build.VERSION.SDK_INT));
    }

    private void setupPicassoSection() {
        boolean picassoDebuggingValue = picassoDebugging.get();
        picasso.setDebugging(picassoDebuggingValue);
        picassoIndicatorView.setChecked(picassoDebuggingValue);
        picassoIndicatorView.setOnCheckedChangeListener((button, isChecked) -> {
            Timber.d("Setting Picasso debugging to " + isChecked);
            picasso.setDebugging(isChecked);
            picassoDebugging.set(isChecked);
        });

        refreshPicassoStats();
    }

    private void refreshPicassoStats() {
        StatsSnapshot snapshot = picasso.getSnapshot();
        String size = getSizeString(snapshot.size);
        String total = getSizeString(snapshot.maxSize);
        int percentage = (int) ((1f * snapshot.size / snapshot.maxSize) * 100);
        picassoCacheSizeView.setText(size + " / " + total + " (" + percentage + "%)");
        picassoCacheHitView.setText(String.valueOf(snapshot.cacheHits));
        picassoCacheMissView.setText(String.valueOf(snapshot.cacheMisses));
        picassoDecodedView.setText(String.valueOf(snapshot.originalBitmapCount));
        picassoDecodedTotalView.setText(getSizeString(snapshot.totalOriginalBitmapSize));
        picassoDecodedAvgView.setText(getSizeString(snapshot.averageOriginalBitmapSize));
        picassoTransformedView.setText(String.valueOf(snapshot.transformedBitmapCount));
        picassoTransformedTotalView.setText(getSizeString(snapshot.totalTransformedBitmapSize));
        picassoTransformedAvgView.setText(getSizeString(snapshot.averageTransformedBitmapSize));
    }

    private void applyAnimationSpeed(int multiplier) {
        try {
            Method method = ValueAnimator.class.getDeclaredMethod("setDurationScale", float.class);
            method.invoke(null, (float) multiplier);
        } catch (Exception e) {
            throw new RuntimeException("Unable to apply animation speed.", e);
        }
    }

    private static String getDensityString(DisplayMetrics displayMetrics) {
        switch (displayMetrics.densityDpi) {
            case DisplayMetrics.DENSITY_LOW:
                return "ldpi";
            case DisplayMetrics.DENSITY_MEDIUM:
                return "mdpi";
            case DisplayMetrics.DENSITY_HIGH:
                return "hdpi";
            case DisplayMetrics.DENSITY_XHIGH:
                return "xhdpi";
            case DisplayMetrics.DENSITY_XXHIGH:
                return "xxhdpi";
            case DisplayMetrics.DENSITY_XXXHIGH:
                return "xxxhdpi";
            case DisplayMetrics.DENSITY_TV:
                return "tvdpi";
            default:
                return "unknown";
        }
    }

    private static String getSizeString(long bytes) {
        String[] units = new String[] { "B", "KB", "MB", "GB" };
        int unit = 0;
        while (bytes >= 1024) {
            bytes /= 1024;
            unit += 1;
        }
        return bytes + units[unit];
    }

    private void showNewNetworkProxyDialog(final ProxyAdapter proxyAdapter) {
        final int originalSelection = networkProxy.isSet() ? ProxyAdapter.PROXY : ProxyAdapter.NONE;

        View view = LayoutInflater.from(app).inflate(R.layout.debug_drawer_network_proxy, null);
        final EditText host = (EditText) view.findViewById(R.id.debug_drawer_network_proxy_host);

        new AlertDialog.Builder(activity) //
                .setTitle("Set Network Proxy")
                .setView(view)
                .setNegativeButton("Cancel", (dialog, i) -> {
                    networkProxyView.setSelection(originalSelection);
                    dialog.cancel();
                })
                .setPositiveButton("Use", (dialog, i) -> {
                    String theHost = host.getText().toString();
                    if (!Strings.isBlank(theHost)) {
                        String[] parts = theHost.split(":", 2);
                        SocketAddress address =
                                InetSocketAddress.createUnresolved(parts[0], Integer.parseInt(parts[1]));

                        networkProxy.set(theHost); // Persist across restarts.
                        proxyAdapter.notifyDataSetChanged(); // Tell the spinner to update.
                        networkProxyView.setSelection(ProxyAdapter.PROXY); // And show the proxy.

                        client.setProxy(new Proxy(HTTP, address));
                    } else {
                        networkProxyView.setSelection(originalSelection);
                    }
                })
                .setOnCancelListener(dialogInterface -> networkProxyView.setSelection(originalSelection))
                .show();
    }

    private void showCustomEndpointDialog(final int originalSelection, String defaultUrl) {
        View view = LayoutInflater.from(app).inflate(R.layout.debug_drawer_network_endpoint, null);
        final EditText url = (EditText) view.findViewById(R.id.debug_drawer_network_endpoint_url);
        url.setText(defaultUrl);
        url.setSelection(url.length());

        new AlertDialog.Builder(activity) //
                .setTitle("Set Network Endpoint")
                .setView(view)
                .setNegativeButton("Cancel", (dialog, i) -> {
                    endpointView.setSelection(originalSelection);
                    dialog.cancel();
                })
                .setPositiveButton("Use", (dialog, i) -> {
                    String theUrl = url.getText().toString();
                    if (!Strings.isBlank(theUrl)) {
                        setEndpointAndRelaunch(theUrl);
                    } else {
                        endpointView.setSelection(originalSelection);
                    }
                })
                .setOnCancelListener(dialogInterface -> endpointView.setSelection(originalSelection))
                .show();
    }

    private void setEndpointAndRelaunch(String endpoint) {
        Timber.d("Setting network endpoint to %s", endpoint);
        networkEndpoint.set(endpoint);

        Intent newApp = new Intent(app, MainActivity.class);
        newApp.setFlags(FLAG_ACTIVITY_CLEAR_TASK | FLAG_ACTIVITY_NEW_TASK);
        app.startActivity(newApp);
        app.buildObjectGraphAndInject();
    }
}




Java Source Code List

com.ponyvillelive.app.DebugPvlModule.java
com.ponyvillelive.app.Modules.java
com.ponyvillelive.app.Modules.java
com.ponyvillelive.app.PvlApp.java
com.ponyvillelive.app.PvlModule.java
com.ponyvillelive.app.model.ArrayResponse.java
com.ponyvillelive.app.model.DebugData.java
com.ponyvillelive.app.model.Entity.java
com.ponyvillelive.app.model.MapResponse.java
com.ponyvillelive.app.model.NowPlayingMeta.java
com.ponyvillelive.app.model.ObjectResponse.java
com.ponyvillelive.app.model.Show.java
com.ponyvillelive.app.model.SongWrapper.java
com.ponyvillelive.app.model.Song.java
com.ponyvillelive.app.model.StationMeta.java
com.ponyvillelive.app.model.Station.java
com.ponyvillelive.app.net.API.java
com.ponyvillelive.app.net.DebugNetModule.java
com.ponyvillelive.app.net.MockAPI.java
com.ponyvillelive.app.net.NetModule.java
com.ponyvillelive.app.prefs.AnimationSpeed.java
com.ponyvillelive.app.prefs.ApiEndpoint.java
com.ponyvillelive.app.prefs.ApiEndpoints.java
com.ponyvillelive.app.prefs.BooleanPreference.java
com.ponyvillelive.app.prefs.Endpoint.java
com.ponyvillelive.app.prefs.Endpoints.java
com.ponyvillelive.app.prefs.IntPreference.java
com.ponyvillelive.app.prefs.IsMockMode.java
com.ponyvillelive.app.prefs.MockDownloader.java
com.ponyvillelive.app.prefs.NetworkProxy.java
com.ponyvillelive.app.prefs.ObjectPreference.java
com.ponyvillelive.app.prefs.PicassoDebugging.java
com.ponyvillelive.app.prefs.PixelGridEnabled.java
com.ponyvillelive.app.prefs.PixelRatioEnabled.java
com.ponyvillelive.app.prefs.ScalpelEnabled.java
com.ponyvillelive.app.prefs.ScalpelWireframeEnabled.java
com.ponyvillelive.app.prefs.SeenDebugDrawer.java
com.ponyvillelive.app.prefs.StringPreference.java
com.ponyvillelive.app.ui.ActionbarHideSlidePanelListener.java
com.ponyvillelive.app.ui.ActivityHierarchyServer.java
com.ponyvillelive.app.ui.AnimationSpeedAdapter.java
com.ponyvillelive.app.ui.AppContainer.java
com.ponyvillelive.app.ui.BindableAdapter.java
com.ponyvillelive.app.ui.BottomDrawerFragment.java
com.ponyvillelive.app.ui.DebugAppContainer.java
com.ponyvillelive.app.ui.DebugUiModule.java
com.ponyvillelive.app.ui.EnumAdapter.java
com.ponyvillelive.app.ui.HierarchyTreeChangeListener.java
com.ponyvillelive.app.ui.MainActivity.java
com.ponyvillelive.app.ui.NetworkDelayAdapter.java
com.ponyvillelive.app.ui.NetworkErrorAdapter.java
com.ponyvillelive.app.ui.NetworkVarianceAdapter.java
com.ponyvillelive.app.ui.ProxyAdapter.java
com.ponyvillelive.app.ui.ServerEndpointAdapter.java
com.ponyvillelive.app.ui.SocketActivityHierarchyServer.java
com.ponyvillelive.app.ui.StationAdapter.java
com.ponyvillelive.app.ui.StationFragment.java
com.ponyvillelive.app.ui.TrackListAdapter.java
com.ponyvillelive.app.ui.UiModule.java
com.ponyvillelive.app.util.Strings.java