Bug 982559 - use intent data to start app from legacy shorcut; r=wesj
authorMyk Melez <myk@mozilla.org>
Fri, 28 Mar 2014 11:27:46 -0700
changeset 175894 0c0176febdf09aa4bffa7e0004642fb66ec8cd32
parent 175893 e44d921f23dc824f1cb381d2d2e553cc4e4367ee
child 175895 f65515f94aabced0fe4e8ffdc6a0b82505df746a
push id41643
push usermyk@mozilla.com
push dateFri, 28 Mar 2014 18:28:06 +0000
treeherdermozilla-inbound@0c0176febdf0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswesj
bugs982559
milestone31.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 982559 - use intent data to start app from legacy shorcut; r=wesj
mobile/android/base/webapp/WebappImpl.java
--- a/mobile/android/base/webapp/WebappImpl.java
+++ b/mobile/android/base/webapp/WebappImpl.java
@@ -46,17 +46,20 @@ public class WebappImpl extends GeckoApp
     private static final String LOGTAG = "GeckoWebappImpl";
 
     private URL mOrigin;
     private TextView mTitlebarText = null;
     private View mTitlebar = null;
 
     private View mSplashscreen;
 
+    private boolean mIsApk = true;
     private ApkResources mApkResources;
+    private String mManifestUrl;
+    private String mAppName;
 
     protected int getIndex() { return 0; }
 
     @Override
     public int getLayout() { return R.layout.web_app; }
 
     @Override
     public boolean hasTabsSideBar() { return false; }
@@ -74,28 +77,46 @@ public class WebappImpl extends GeckoApp
         if (extras == null) {
             extras = new Bundle();
         }
 
         boolean isInstalled = extras.getBoolean("isInstalled", false);
         String packageName = extras.getString("packageName");
 
         if (packageName == null) {
-            // TODO Migration path!
-            Log.w(LOGTAG, "Can't find package name for webapp");
-            setResult(RESULT_CANCELED);
-            finish();
-        }
+            Log.w(LOGTAG, "no package name; treating as legacy shortcut");
+
+            mIsApk = false;
+
+            // Shortcut apps are already installed.
+            isInstalled = true;
 
-        try {
-            mApkResources = new ApkResources(this, packageName);
-        } catch (NameNotFoundException e) {
-            Log.e(LOGTAG, "Can't find package for webapp " + packageName, e);
-            setResult(RESULT_CANCELED);
-            finish();
+            Uri data = getIntent().getData();
+            if (data == null) {
+                Log.wtf(LOGTAG, "can't get manifest URL from shortcut data");
+                setResult(RESULT_CANCELED);
+                finish();
+                return;
+            }
+            mManifestUrl = data.toString();
+
+            String shortcutName = extras.getString(Intent.EXTRA_SHORTCUT_NAME);
+            mAppName = shortcutName != null ? shortcutName : "Web App";
+        } else {
+            try {
+                mApkResources = new ApkResources(this, packageName);
+            } catch (NameNotFoundException e) {
+                Log.e(LOGTAG, "Can't find package for webapp " + packageName, e);
+                setResult(RESULT_CANCELED);
+                finish();
+                return;
+            }
+
+            mManifestUrl = mApkResources.getManifestUrl();
+            mAppName = mApkResources.getAppName();
         }
 
         // start Gecko.
         super.onCreate(savedInstance);
 
         mTitlebarText = (TextView)findViewById(R.id.webapp_title);
         mTitlebar = findViewById(R.id.webapp_titlebar);
         mSplashscreen = findViewById(R.id.splashscreen);
@@ -108,17 +129,17 @@ public class WebappImpl extends GeckoApp
         allocator.maybeMigrateOldPrefs(index);
 
         String origin = allocator.getOrigin(index);
         boolean isInstallCompleting = (origin == null);
 
         if (!GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoRunning) || !isInstalled || isInstallCompleting) {
             // Show the splash screen if we need to start Gecko, or we need to install this.
             overridePendingTransition(R.anim.grow_fade_in_center, android.R.anim.fade_out);
-            showSplash(true);
+            showSplash();
         } else {
             mSplashscreen.setVisibility(View.GONE);
         }
 
         if (!isInstalled || isInstallCompleting) {
             InstallHelper installHelper = new InstallHelper(getApplicationContext(), mApkResources, this);
             if (!isInstalled) {
                 // start the vanilla install.
@@ -129,51 +150,59 @@ public class WebappImpl extends GeckoApp
                 }
             } else {
                 // an install is already happening, so we should let it complete.
                 Log.i(LOGTAG, "Waiting for existing install to complete");
                 installHelper.registerGeckoListener();
             }
             return;
         } else {
-            launchWebapp(origin, mApkResources.getManifestUrl(), mApkResources.getAppName());
+            launchWebapp(origin);
         }
 
-        setTitle(mApkResources.getAppName());
+        setTitle(mAppName);
     }
 
     @Override
     protected String getURIFromIntent(Intent intent) {
         String uri = super.getURIFromIntent(intent);
         if (uri != null) {
             return uri;
         }
         // This is where we construct the URL from the Intent from the
         // the synthesized APK.
 
         // TODO Translate AndroidIntents into WebActivities here.
-        return mApkResources.getManifestUrl();
+        if (mIsApk) {
+            return mApkResources.getManifestUrl();
+        }
+
+        // If this is a legacy shortcut, then we should have been able to get
+        // the URI from the intent data.  Otherwise, we should have been able
+        // to get it from the APK resources.  So we should never get here.
+        Log.wtf(LOGTAG, "Couldn't get URI from intent nor APK resources");
+        return null;
     }
 
     @Override
     protected void loadStartupTab(String uri) {
         // NOP
     }
 
-    private void showSplash(boolean isApk) {
+    private void showSplash() {
 
         // get the favicon dominant color, stored when the app was installed
         int dominantColor = Allocator.getInstance().getColor(getIndex());
 
         setBackgroundGradient(dominantColor);
 
         ImageView image = (ImageView)findViewById(R.id.splashscreen_icon);
         Drawable d = null;
 
-        if (isApk) {
+        if (mIsApk) {
             Uri uri = mApkResources.getAppIconUri();
             image.setImageURI(uri);
             d = image.getDrawable();
         } else {
             // look for a logo.png in the profile dir and show it. If we can't find a logo show nothing
             File profile = getProfile().getDir();
             File logoFile = new File(profile, "logo.png");
             if (logoFile.exists()) {
@@ -294,53 +323,66 @@ public class WebappImpl extends GeckoApp
     @Override
     public void installCompleted(InstallHelper installHelper, String event, JSONObject message) {
         if (event == null) {
             return;
         }
 
         if (event.equals("Webapps:Postinstall")) {
             String origin = message.optString("origin");
-            launchWebapp(origin, mApkResources.getManifestUrl(), mApkResources.getAppName());
+            launchWebapp(origin);
         }
     }
 
     @Override
     public void installErrored(InstallHelper installHelper, Exception exception) {
         Log.e(LOGTAG, "Install errored", exception);
     }
 
-    public void launchWebapp(String origin, String manifestUrl, String name) {
+    private void setOrigin(String origin) {
         try {
             mOrigin = new URL(origin);
         } catch (java.net.MalformedURLException ex) {
-            // If we can't parse the this is an app protocol, just settle for not having an origin
+            // If this isn't an app: URL, just settle for not having an origin.
             if (!origin.startsWith("app://")) {
                 return;
             }
 
-            // If that failed fall back to the origin stored in the shortcut
-            Log.i(LOGTAG, "Webapp is not registered with allocator");
-            Uri data = getIntent().getData();
-            if (data != null) {
-                try {
-                    mOrigin = new URL(data.toString());
-                } catch (java.net.MalformedURLException ex2) {
-                    Log.e(LOGTAG, "Unable to parse intent url: ", ex);
+            // If that failed fall back to the origin stored in the shortcut.
+            if (!mIsApk) {
+                Log.i(LOGTAG, "Origin is app: URL; falling back to intent URL");
+                Uri data = getIntent().getData();
+                if (data != null) {
+                    try {
+                        mOrigin = new URL(data.toString());
+                    } catch (java.net.MalformedURLException ex2) {
+                        Log.e(LOGTAG, "Unable to parse intent URL: ", ex);
+                    }
                 }
             }
         }
+    }
+
+    public void launchWebapp(String origin) {
+        setOrigin(origin);
+
         try {
             JSONObject launchObject = new JSONObject();
-            launchObject.putOpt("url", manifestUrl);
-            launchObject.putOpt("name", mApkResources.getAppName());
+            launchObject.putOpt("url", mManifestUrl);
+            launchObject.putOpt("name", mAppName);
             Log.i(LOGTAG, "Trying to launch: " + launchObject);
             GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Webapps:Load", launchObject.toString()));
         } catch (JSONException e) {
             Log.e(LOGTAG, "Error populating launch message", e);
         }
     }
 
     @Override
     protected boolean getIsDebuggable() {
-        return mApkResources.isDebuggable();
+        if (mIsApk) {
+            return mApkResources.isDebuggable();
+        }
+
+        // This is a legacy shortcut, which didn't provide a way to determine
+        // that the app is debuggable, so we say the app is not debuggable.
+        return false;
     }
 }