Bug 839854 - Protect against getChildAt returning a null view during a rotation. r=mfinkle, a=lsblakk
authorWes Johnston <wjohnston@mozilla.com>
Tue, 09 Jul 2013 15:18:56 -0700
changeset 147990 1dffe1098d37ff4b1402198fd92af243d664c09d
parent 147989 e3d234674a863d7baaebf7a534684919cb12cd02
child 147991 0d566d5133bec18b3f080ef6f700fc0d65422b4d
push id2697
push userbbajaj@mozilla.com
push dateMon, 05 Aug 2013 18:49:53 +0000
treeherdermozilla-beta@dfec938c7b63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmfinkle, lsblakk
bugs839854
milestone24.0a2
Bug 839854 - Protect against getChildAt returning a null view during a rotation. r=mfinkle, a=lsblakk
mobile/android/base/widget/TopSitesView.java
--- a/mobile/android/base/widget/TopSitesView.java
+++ b/mobile/android/base/widget/TopSitesView.java
@@ -119,16 +119,21 @@ public class TopSitesView extends GridVi
 
                 MenuInflater inflater = mActivity.getMenuInflater();
                 inflater.inflate(R.menu.abouthome_topsites_contextmenu, menu);
 
                 // If nothing is pinned at all, hide both clear items
                 // We can assume that the adapter count and view count are the same in this case because our grid view
                 // force all items to be visible all the time
                 View view = getChildAt(info.position);
+                // The grid view might get temporarily out of sync with the
+                // adapter refreshes (e.g. on device rotation)
+                if (view == null) {
+                    return;
+                }
                 TopSitesViewHolder holder = (TopSitesViewHolder) view.getTag();
                 if (TextUtils.isEmpty(holder.getUrl())) {
                     menu.findItem(R.id.abouthome_open_new_tab).setVisible(false);
                     menu.findItem(R.id.abouthome_open_private_tab).setVisible(false);
                     menu.findItem(R.id.abouthome_topsites_pin).setVisible(false);
                     menu.findItem(R.id.abouthome_topsites_unpin).setVisible(false);
                 } else if (holder.isPinned()) {
                     menu.findItem(R.id.abouthome_topsites_pin).setVisible(false);
@@ -283,18 +288,19 @@ public class TopSitesView extends GridVi
     }
 
     private void updateTopSitesThumbnails(Map<String, Bitmap> thumbnails) {
         for (int i = 0; i < mTopSitesAdapter.getCount(); i++) {
             final View view = getChildAt(i);
 
             // The grid view might get temporarily out of sync with the
             // adapter refreshes (e.g. on device rotation)
-            if (view == null)
+            if (view == null) {
                 continue;
+            }
 
             TopSitesViewHolder holder = (TopSitesViewHolder)view.getTag();
             final String url = holder.getUrl();
             if (TextUtils.isEmpty(url)) {
                 holder.thumbnailView.setScaleType(ImageView.ScaleType.FIT_CENTER);
                 holder.thumbnailView.setImageResource(R.drawable.abouthome_thumbnail_add);
                 holder.thumbnailView.setBackgroundColor(mThumbnailBackground);
             } else {
@@ -500,16 +506,21 @@ public class TopSitesView extends GridVi
 
             return buildView(url, title, pinned, convertView);
         }
     }
 
     private void clearThumbnailsWithUrl(final String url) {
         for (int i = 0; i < mTopSitesAdapter.getCount(); i++) {
             final View view = getChildAt(i);
+            // The grid view might get temporarily out of sync with the
+            // adapter refreshes (e.g. on device rotation)
+            if (view == null) {
+                continue;
+            }
             final TopSitesViewHolder holder = (TopSitesViewHolder) view.getTag();
 
             if (holder.getUrl().equals(url)) {
                 clearThumbnail(holder);
             }
         }
     }
 
@@ -540,16 +551,21 @@ public class TopSitesView extends GridVi
         openTab(menuInfo, Tabs.LOADURL_NEW_TAB | Tabs.LOADURL_PRIVATE | Tabs.LOADURL_BACKGROUND);
     }
 
     public void unpinSite(ContextMenuInfo menuInfo, final UnpinFlags flags) {
         AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
         final int position = info.position;
 
         final View v = getChildAt(position);
+        // The grid view might get temporarily out of sync with the
+        // adapter refreshes (e.g. on device rotation)
+        if (v == null) {
+            return;
+        }
         final TopSitesViewHolder holder = (TopSitesViewHolder) v.getTag();
         final String url = holder.getUrl();
         // Quickly update the view so that there isn't as much lag between the request and response
         clearThumbnail(holder);
         (new UiAsyncTask<Void, Void, Void>(ThreadUtils.getBackgroundHandler()) {
             @Override
             public Void doInBackground(Void... params) {
                 final ContentResolver resolver = mContext.getContentResolver();
@@ -558,16 +574,21 @@ public class TopSitesView extends GridVi
             }
         }).execute();
     }
 
     public void pinSite(ContextMenuInfo menuInfo) {
         AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
         final int position = info.position;
         View v = getChildAt(position);
+        // The grid view might get temporarily out of sync with the
+        // adapter refreshes (e.g. on device rotation)
+        if (v == null) {
+            return;
+        }
 
         final TopSitesViewHolder holder = (TopSitesViewHolder) v.getTag();
         holder.setPinned(true);
 
         // update the database on a background thread
         (new UiAsyncTask<Void, Void, Void>(ThreadUtils.getBackgroundHandler()) {
             @Override
             public Void doInBackground(Void... params) {
@@ -589,16 +610,21 @@ public class TopSitesView extends GridVi
         }
         return url;
     }
 
     public void editSite(ContextMenuInfo menuInfo) {
         AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
         int position = info.position;
         View v = getChildAt(position);
+        // The grid view might get temporarily out of sync with the
+        // adapter refreshes (e.g. on device rotation)
+        if (v == null) {
+            return;
+        }
 
         TopSitesViewHolder holder = (TopSitesViewHolder) v.getTag();
         // Decode "user-entered" URLs before showing them to the user to edit.
         editSite(decodeUserEnteredUrl(holder.getUrl()), position);
     }
 
     // Edit the site at position. Provide a url to start editing with
     public void editSite(String url, final int position) {
@@ -611,16 +637,21 @@ public class TopSitesView extends GridVi
 
         int requestCode = GeckoAppShell.sActivityHelper.makeRequestCode(new ActivityResultHandler() {
             @Override
             public void onActivityResult(int resultCode, Intent data) {
                 if (resultCode == Activity.RESULT_CANCELED || data == null)
                     return;
 
                 final View v = getChildAt(position);
+                // The grid view might get temporarily out of sync with the
+                // adapter refreshes (e.g. on device rotation)
+                if (v == null) {
+                    return;
+                }
                 final TopSitesViewHolder holder = (TopSitesViewHolder) v.getTag();
 
                 String title = data.getStringExtra(AwesomeBar.TITLE_KEY);
                 String url = data.getStringExtra(AwesomeBar.URL_KEY);
 
                 // Bail if the user entered an empty string.
                 if (TextUtils.isEmpty(url)) {
                     return;