Merge "Modifying RemoteViewsFactory interface"
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index 1c0a2bb..365133b 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -29,6 +29,7 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
+import android.os.RemoteException;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -156,13 +157,16 @@
                                 // create in response to this bind
                                 factory.onDataSetChanged();
                             }
-                        } catch (Exception e) {
+                        } catch (RemoteException e) {
                             Log.e(TAG, "Error notifying factory of data set changed in " +
                                         "onServiceConnected(): " + e.getMessage());
 
                             // Return early to prevent anything further from being notified
                             // (effectively nothing has changed)
                             return;
+                        } catch (RuntimeException e) {
+                            Log.e(TAG, "Error notifying factory of data set changed in " +
+                                    "onServiceConnected(): " + e.getMessage());
                         }
 
                         // Request meta data so that we have up to date data when calling back to
@@ -777,7 +781,7 @@
                 tmpMetaData.count = count;
                 tmpMetaData.setLoadingViewTemplates(loadingView, firstView);
             }
-        } catch (Exception e) {
+        } catch(RemoteException e) {
             processException("updateMetaData", e);
         }
     }
@@ -792,12 +796,15 @@
         try {
             remoteViews = factory.getViewAt(position);
             itemId = factory.getItemId(position);
-        } catch (Exception e) {
+        } catch (RemoteException e) {
             Log.e(TAG, "Error in updateRemoteViews(" + position + "): " + e.getMessage());
 
             // Return early to prevent additional work in re-centering the view cache, and
             // swapping from the loading view
             return;
+        } catch (RuntimeException e) {
+            Log.e(TAG, "Error in updateRemoteViews(" + position + "): " + e.getMessage());
+            return;
         }
 
         if (remoteViews == null) {
@@ -971,18 +978,20 @@
         return getCount() <= 0;
     }
 
-
     private void onNotifyDataSetChanged() {
         // Complete the actual notifyDataSetChanged() call initiated earlier
         IRemoteViewsFactory factory = mServiceConnection.getRemoteViewsFactory();
         try {
             factory.onDataSetChanged();
-        } catch (Exception e) {
+        } catch (RemoteException e) {
             Log.e(TAG, "Error in updateNotifyDataSetChanged(): " + e.getMessage());
 
             // Return early to prevent from further being notified (since nothing has
             // changed)
             return;
+        } catch (RuntimeException e) {
+            Log.e(TAG, "Error in updateNotifyDataSetChanged(): " + e.getMessage());
+            return;
         }
 
         // Flush the cache so that we can reload new items from the service
diff --git a/core/java/android/widget/RemoteViewsService.java b/core/java/android/widget/RemoteViewsService.java
index e0b08d4..7ba4777 100644
--- a/core/java/android/widget/RemoteViewsService.java
+++ b/core/java/android/widget/RemoteViewsService.java
@@ -138,34 +138,87 @@
             return mIsCreated;
         }
         public synchronized void onDataSetChanged() {
-            mFactory.onDataSetChanged();
+            try {
+                mFactory.onDataSetChanged();
+            } catch (Exception ex) {
+                Thread t = Thread.currentThread();
+                Thread.getDefaultUncaughtExceptionHandler().uncaughtException(t, ex);
+            }
         }
         public synchronized int getCount() {
-            return mFactory.getCount();
+            int count = 0;
+            try {
+                count = mFactory.getCount();
+            } catch (Exception ex) {
+                Thread t = Thread.currentThread();
+                Thread.getDefaultUncaughtExceptionHandler().uncaughtException(t, ex);
+            }
+            return count;
         }
         public synchronized RemoteViews getViewAt(int position) {
-            RemoteViews rv = mFactory.getViewAt(position);
-            rv.setIsWidgetCollectionChild(true);
+            RemoteViews rv = null;
+            try {
+                rv = mFactory.getViewAt(position);
+                if (rv != null) {
+                    rv.setIsWidgetCollectionChild(true);
+                }
+            } catch (Exception ex) {
+                Thread t = Thread.currentThread();
+                Thread.getDefaultUncaughtExceptionHandler().uncaughtException(t, ex);
+            }
             return rv;
         }
         public synchronized RemoteViews getLoadingView() {
-            return mFactory.getLoadingView();
+            RemoteViews rv = null;
+            try {
+                rv = mFactory.getLoadingView();
+            } catch (Exception ex) {
+                Thread t = Thread.currentThread();
+                Thread.getDefaultUncaughtExceptionHandler().uncaughtException(t, ex);
+            }
+            return rv;
         }
         public synchronized int getViewTypeCount() {
-            return mFactory.getViewTypeCount();
+            int count = 0;
+            try {
+                count = mFactory.getViewTypeCount();
+            } catch (Exception ex) {
+                Thread t = Thread.currentThread();
+                Thread.getDefaultUncaughtExceptionHandler().uncaughtException(t, ex);
+            }
+            return count;
         }
         public synchronized long getItemId(int position) {
-            return mFactory.getItemId(position);
+            long id = 0;
+            try {
+                id = mFactory.getItemId(position);
+            } catch (Exception ex) {
+                Thread t = Thread.currentThread();
+                Thread.getDefaultUncaughtExceptionHandler().uncaughtException(t, ex);
+            }
+            return id;
         }
         public synchronized boolean hasStableIds() {
-            return mFactory.hasStableIds();
+            boolean hasStableIds = false;
+            try {
+                hasStableIds = mFactory.hasStableIds();
+            } catch (Exception ex) {
+                Thread t = Thread.currentThread();
+                Thread.getDefaultUncaughtExceptionHandler().uncaughtException(t, ex);
+            }
+            return hasStableIds;
         }
         public void onDestroy(Intent intent) {
             synchronized (sLock) {
                 Intent.FilterComparison fc = new Intent.FilterComparison(intent);
                 if (RemoteViewsService.sRemoteViewFactories.containsKey(fc)) {
                     RemoteViewsFactory factory = RemoteViewsService.sRemoteViewFactories.get(fc);
-                    factory.onDestroy();
+                    try {
+                        factory.onDestroy();
+                    } catch (Exception ex) {
+                        Thread t = Thread.currentThread();
+                        Thread.getDefaultUncaughtExceptionHandler().uncaughtException(t, ex);
+                    }
                     RemoteViewsService.sRemoteViewFactories.remove(fc);
                 }
             }
diff --git a/core/java/com/android/internal/widget/IRemoteViewsFactory.aidl b/core/java/com/android/internal/widget/IRemoteViewsFactory.aidl
index 5857acb..18076c4 100644
--- a/core/java/com/android/internal/widget/IRemoteViewsFactory.aidl
+++ b/core/java/com/android/internal/widget/IRemoteViewsFactory.aidl
@@ -22,7 +22,7 @@
 /** {@hide} */
 interface IRemoteViewsFactory {
     void onDataSetChanged();
-    void onDestroy(in Intent intent);
+    oneway void onDestroy(in Intent intent);
     int getCount();
     RemoteViews getViewAt(int position);
     RemoteViews getLoadingView();
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index a4a95a0..c03b994 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -541,7 +541,9 @@
                     IRemoteViewsFactory.Stub.asInterface(service);
                 try {
                     cb.onDestroy(intent);
-                } catch (Exception e) {
+                } catch (RemoteException e) {
+                    e.printStackTrace();
+                } catch (RuntimeException e) {
                     e.printStackTrace();
                 }
                 mContext.unbindService(this);