Bug 982559 - Use intent data to start app from legacy shorcut. r=wesj, a=sledru
authorMyk Melez <myk@mozilla.org>
Fri, 28 Mar 2014 11:27:46 -0700
changeset 185252 34beb0f99c5ae65f659e9d597a2e427808fe0620
parent 185251 123d3d93353167b967be33b69dbd0973317676f8
child 185253 1739072e5cbbb6c18a0b2b6ea13275b7f9cf2b79
push id5571
push userryanvm@gmail.com
push dateTue, 01 Apr 2014 15:34:30 +0000
treeherdermozilla-aurora@a3ddaade8cca [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswesj, sledru
bugs982559
milestone30.0a2
Bug 982559 - Use intent data to start app from legacy shorcut. r=wesj, a=sledru
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;
     }
 }