mobile/android/base/WebappImpl.java

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/mobile/android/base/WebappImpl.java	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,221 @@
     1.4 +/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
     1.5 + * This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +package org.mozilla.gecko;
    1.10 +
    1.11 +import android.content.Intent;
    1.12 +import android.os.Bundle;
    1.13 +import android.util.Log;
    1.14 +import android.view.View;
    1.15 +import android.view.MenuItem;
    1.16 +import android.widget.TextView;
    1.17 +import android.widget.RelativeLayout;
    1.18 +import android.content.Context;
    1.19 +import android.content.SharedPreferences;
    1.20 +import android.graphics.Bitmap;
    1.21 +import android.graphics.Color;
    1.22 +import android.graphics.drawable.Drawable;
    1.23 +import android.graphics.drawable.GradientDrawable;
    1.24 +import android.view.animation.AnimationUtils;
    1.25 +import android.view.animation.Animation;
    1.26 +import android.widget.ImageView;
    1.27 +import android.view.Display;
    1.28 +
    1.29 +import java.io.File;
    1.30 +import java.net.URI;
    1.31 +
    1.32 +public class WebappImpl extends GeckoApp {
    1.33 +    private static final String LOGTAG = "GeckoWebappImpl";
    1.34 +
    1.35 +    private URI mOrigin;
    1.36 +    private TextView mTitlebarText = null;
    1.37 +    private View mTitlebar = null;
    1.38 +
    1.39 +    private View mSplashscreen;
    1.40 +
    1.41 +    protected int getIndex() { return 0; }
    1.42 +
    1.43 +    @Override
    1.44 +    public int getLayout() { return R.layout.web_app; }
    1.45 +
    1.46 +    @Override
    1.47 +    public boolean hasTabsSideBar() { return false; }
    1.48 +
    1.49 +    @Override
    1.50 +    public void onCreate(Bundle savedInstanceState)
    1.51 +    {
    1.52 +        super.onCreate(savedInstanceState);
    1.53 +
    1.54 +        mSplashscreen = (RelativeLayout) findViewById(R.id.splashscreen);
    1.55 +        if (!GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoRunning)) {
    1.56 +            overridePendingTransition(R.anim.grow_fade_in_center, android.R.anim.fade_out);
    1.57 +            showSplash();
    1.58 +        }
    1.59 +
    1.60 +        String action = getIntent().getAction();
    1.61 +        Bundle extras = getIntent().getExtras();
    1.62 +        String title = extras != null ? extras.getString(Intent.EXTRA_SHORTCUT_NAME) : null;
    1.63 +        setTitle(title != null ? title : "Web App");
    1.64 +
    1.65 +        mTitlebarText = (TextView)findViewById(R.id.webapp_title);
    1.66 +        mTitlebar = findViewById(R.id.webapp_titlebar);
    1.67 +        if (!action.startsWith(ACTION_WEBAPP_PREFIX)) {
    1.68 +            Log.e(LOGTAG, "Webapp launch, but intent action is " + action + "!");
    1.69 +            return;
    1.70 +        }
    1.71 +
    1.72 +        // Try to use the origin stored in the WebappAllocator first
    1.73 +        String origin = WebappAllocator.getInstance(this).getAppForIndex(getIndex());
    1.74 +        try {
    1.75 +            mOrigin = new URI(origin);
    1.76 +        } catch (java.net.URISyntaxException ex) {
    1.77 +            // If we can't parse the this is an app protocol, just settle for not having an origin
    1.78 +            if (!origin.startsWith("app://")) {
    1.79 +                return;
    1.80 +            }
    1.81 +
    1.82 +            // If that failed fall back to the origin stored in the shortcut
    1.83 +            Log.i(LOGTAG, "Webapp is not registered with allocator");
    1.84 +            try {
    1.85 +                mOrigin = new URI(getIntent().getData().toString());
    1.86 +            } catch (java.net.URISyntaxException ex2) {
    1.87 +                Log.e(LOGTAG, "Unable to parse intent url: ", ex);
    1.88 +            }
    1.89 +        }
    1.90 +    }
    1.91 +
    1.92 +    @Override
    1.93 +    protected void loadStartupTab(String uri) {
    1.94 +        String action = getIntent().getAction();
    1.95 +        if (GeckoApp.ACTION_WEBAPP_PREFIX.equals(action)) {
    1.96 +            // This action assumes the uri is not an installed Webapp. We will
    1.97 +            // use the WebappAllocator to register the uri with an Android
    1.98 +            // process so it can run chromeless.
    1.99 +            int index = WebappAllocator.getInstance(this).findAndAllocateIndex(uri, "App", (Bitmap) null);
   1.100 +            Intent appIntent = GeckoAppShell.getWebappIntent(index, uri);
   1.101 +            startActivity(appIntent);
   1.102 +            finish();
   1.103 +        }
   1.104 +    }
   1.105 +
   1.106 +    private void showSplash() {
   1.107 +        SharedPreferences prefs = getSharedPreferences("webapps", Context.MODE_PRIVATE | Context.MODE_MULTI_PROCESS);
   1.108 +
   1.109 +        // get the favicon dominant color, stored when the app was installed
   1.110 +        int[] colors = new int[2];
   1.111 +        int dominantColor = prefs.getInt(WebappAllocator.iconKey(getIndex()), -1);
   1.112 +
   1.113 +        // now lighten it, to ensure that the icon stands out in the center
   1.114 +        float[] f = new float[3];
   1.115 +        Color.colorToHSV(dominantColor, f);
   1.116 +        f[2] = Math.min(f[2]*2, 1.0f);
   1.117 +        colors[0] = Color.HSVToColor(255, f);
   1.118 +
   1.119 +        // now generate a second, slightly darker version of the same color
   1.120 +        f[2] *= 0.75;
   1.121 +        colors[1] = Color.HSVToColor(255, f);
   1.122 +
   1.123 +        // Draw the background gradient
   1.124 +        GradientDrawable gd = new GradientDrawable(GradientDrawable.Orientation.TL_BR, colors);
   1.125 +        gd.setGradientType(GradientDrawable.RADIAL_GRADIENT);
   1.126 +        Display display = getWindowManager().getDefaultDisplay();
   1.127 +        gd.setGradientCenter(0.5f, 0.5f);
   1.128 +        gd.setGradientRadius(Math.max(display.getWidth()/2, display.getHeight()/2));
   1.129 +        mSplashscreen.setBackgroundDrawable((Drawable)gd);
   1.130 +
   1.131 +        // look for a logo.png in the profile dir and show it. If we can't find a logo show nothing
   1.132 +        File profile = getProfile().getDir();
   1.133 +        File logoFile = new File(profile, "logo.png");
   1.134 +        if (logoFile.exists()) {
   1.135 +            ImageView image = (ImageView)findViewById(R.id.splashscreen_icon);
   1.136 +            Drawable d = Drawable.createFromPath(logoFile.getPath());
   1.137 +            image.setImageDrawable(d);
   1.138 +
   1.139 +            Animation fadein = AnimationUtils.loadAnimation(this, R.anim.grow_fade_in_center);
   1.140 +            fadein.setStartOffset(500);
   1.141 +            fadein.setDuration(1000);
   1.142 +            image.startAnimation(fadein);
   1.143 +        }
   1.144 +    }
   1.145 +
   1.146 +    @Override
   1.147 +    protected String getDefaultProfileName() {
   1.148 +        String action = getIntent().getAction();
   1.149 +        if (!action.startsWith(ACTION_WEBAPP_PREFIX)) {
   1.150 +            Log.e(LOGTAG, "Webapp launch, but intent action is " + action + "!");
   1.151 +            return null;
   1.152 +        }
   1.153 +
   1.154 +        return "webapp" + action.substring(ACTION_WEBAPP_PREFIX.length());
   1.155 +    }
   1.156 +
   1.157 +    @Override
   1.158 +    protected boolean getSessionRestoreState(Bundle savedInstanceState) {
   1.159 +        // for now webapps never restore your session
   1.160 +        return false;
   1.161 +    }
   1.162 +
   1.163 +    @Override
   1.164 +    public void onTabChanged(Tab tab, Tabs.TabEvents msg, Object data) {
   1.165 +        switch(msg) {
   1.166 +            case SELECTED:
   1.167 +            case LOCATION_CHANGE:
   1.168 +                if (Tabs.getInstance().isSelectedTab(tab)) {
   1.169 +                    final String urlString = tab.getURL();
   1.170 +                    final URI uri;
   1.171 +
   1.172 +                    try {
   1.173 +                        uri = new URI(urlString);
   1.174 +                    } catch (java.net.URISyntaxException ex) {
   1.175 +                        mTitlebarText.setText(urlString);
   1.176 +
   1.177 +                        // If we can't parse the url, and its an app protocol hide
   1.178 +                        // the titlebar and return, otherwise show the titlebar
   1.179 +                        // and the full url
   1.180 +                        if (!urlString.startsWith("app://")) {
   1.181 +                            mTitlebar.setVisibility(View.VISIBLE);
   1.182 +                        } else {
   1.183 +                            mTitlebar.setVisibility(View.GONE);
   1.184 +                        }
   1.185 +                        return;
   1.186 +                    }
   1.187 +
   1.188 +                    if (mOrigin != null && mOrigin.getHost().equals(uri.getHost())) {
   1.189 +                        mTitlebar.setVisibility(View.GONE);
   1.190 +                    } else {
   1.191 +                        mTitlebarText.setText(uri.getScheme() + "://" + uri.getHost());
   1.192 +                        mTitlebar.setVisibility(View.VISIBLE);
   1.193 +                    }
   1.194 +                }
   1.195 +                break;
   1.196 +            case LOADED:
   1.197 +                if (mSplashscreen != null && mSplashscreen.getVisibility() == View.VISIBLE) {
   1.198 +                    Animation fadeout = AnimationUtils.loadAnimation(this, android.R.anim.fade_out);
   1.199 +                    fadeout.setAnimationListener(new Animation.AnimationListener() {
   1.200 +                        @Override
   1.201 +                        public void onAnimationEnd(Animation animation) {
   1.202 +                          mSplashscreen.setVisibility(View.GONE);
   1.203 +                        }
   1.204 +                        @Override
   1.205 +                        public void onAnimationRepeat(Animation animation) { }
   1.206 +                        @Override
   1.207 +                        public void onAnimationStart(Animation animation) { }
   1.208 +                    });
   1.209 +                    mSplashscreen.startAnimation(fadeout);
   1.210 +                }
   1.211 +                break;
   1.212 +            case START:
   1.213 +                if (mSplashscreen != null && mSplashscreen.getVisibility() == View.VISIBLE) {
   1.214 +                    View area = findViewById(R.id.splashscreen_progress);
   1.215 +                    area.setVisibility(View.VISIBLE);
   1.216 +                    Animation fadein = AnimationUtils.loadAnimation(this, android.R.anim.fade_in);
   1.217 +                    fadein.setDuration(1000);
   1.218 +                    area.startAnimation(fadein);
   1.219 +                }
   1.220 +                break;
   1.221 +        }
   1.222 +        super.onTabChanged(tab, msg, data);
   1.223 +    }
   1.224 +};

mercurial