Merge "Fix for crash when PhotoApp deletes last Cam pic" into ub-camera-glacier
diff --git a/src/com/android/camera/CameraActivity.java b/src/com/android/camera/CameraActivity.java
index d05248a..af9af0f 100644
--- a/src/com/android/camera/CameraActivity.java
+++ b/src/com/android/camera/CameraActivity.java
@@ -538,8 +538,9 @@
 
     @Override
     public void onCameraDisabled(int cameraId) {
-        UsageStatistics.instance().cameraFailure(eventprotos.CameraFailure.FailureReason.SECURITY,
-                null);
+        UsageStatistics.instance().cameraFailure(
+                eventprotos.CameraFailure.FailureReason.SECURITY, null,
+                UsageStatistics.NONE, UsageStatistics.NONE);
         Log.w(TAG, "Camera disabled: " + cameraId);
         CameraUtil.showErrorAndFinish(this, R.string.camera_disabled);
     }
@@ -547,7 +548,8 @@
     @Override
     public void onDeviceOpenFailure(int cameraId, String info) {
         UsageStatistics.instance().cameraFailure(
-                eventprotos.CameraFailure.FailureReason.OPEN_FAILURE, info);
+                eventprotos.CameraFailure.FailureReason.OPEN_FAILURE, info,
+                UsageStatistics.NONE, UsageStatistics.NONE);
         Log.w(TAG, "Camera open failure: " + info);
         CameraUtil.showErrorAndFinish(this, R.string.cannot_connect_camera);
     }
@@ -561,7 +563,8 @@
     @Override
     public void onReconnectionFailure(CameraAgent mgr, String info) {
         UsageStatistics.instance().cameraFailure(
-                eventprotos.CameraFailure.FailureReason.RECONNECT_FAILURE, null);
+                eventprotos.CameraFailure.FailureReason.RECONNECT_FAILURE, null,
+                UsageStatistics.NONE, UsageStatistics.NONE);
         Log.w(TAG, "Camera reconnection failure:" + info);
         CameraUtil.showErrorAndFinish(this, R.string.cannot_connect_camera);
     }
@@ -1325,13 +1328,20 @@
                     Log.e(TAG, "Camera error callback. error=" + errorCode);
                 }
                 @Override
-                public void onCameraException(RuntimeException ex) {
+                public void onCameraException(
+                        RuntimeException ex, String commandHistory, int action, int state) {
                     Log.e(TAG, "Camera Exception", ex);
+                    UsageStatistics.instance().cameraFailure(
+                            eventprotos.CameraFailure.FailureReason.API_RUNTIME_EXCEPTION,
+                            commandHistory, action, state);
                     onFatalError();
                 }
                 @Override
                 public void onDispatchThreadException(RuntimeException ex) {
                     Log.e(TAG, "DispatchThread Exception", ex);
+                    UsageStatistics.instance().cameraFailure(
+                            eventprotos.CameraFailure.FailureReason.API_TIMEOUT,
+                            null, UsageStatistics.NONE, UsageStatistics.NONE);
                     onFatalError();
                 }
                 private void onFatalError() {
@@ -1462,7 +1472,7 @@
         mPanoramaViewHelper = new PanoramaViewHelper(this);
         mPanoramaViewHelper.onCreate();
         // Set up the camera preview first so the preview shows up ASAP.
-        mDataAdapter = new CameraDataAdapter(mAppContext, mMainHandler, R.color.photo_placeholder);
+        mDataAdapter = new CameraDataAdapter(mAppContext, R.color.photo_placeholder);
         mDataAdapter.setLocalDataListener(mLocalDataListener);
 
         mPreloader = new Preloader<Integer, AsyncTask>(FILMSTRIP_PRELOAD_AHEAD_ITEMS, mDataAdapter,
diff --git a/src/com/android/camera/PhotoModule.java b/src/com/android/camera/PhotoModule.java
index 8c1c88c..d363591 100644
--- a/src/com/android/camera/PhotoModule.java
+++ b/src/com/android/camera/PhotoModule.java
@@ -313,6 +313,10 @@
     }
 
     private void checkDisplayRotation() {
+        // Need to just be a no-op for the quick resume-pause scenario.
+        if (mPaused) {
+            return;
+        }
         // Set the display orientation if display rotation has changed.
         // Sometimes this happens when the device is held upside
         // down and camera app is opened. Rotation animation will
@@ -456,6 +460,7 @@
         }
         mAppController.getCameraAppUI().transitionToCapture();
         mAppController.getCameraAppUI().showModeOptions();
+        mAppController.setShutterEnabled(true);
     }
 
     @Override
@@ -1267,9 +1272,11 @@
         // If we are already in the middle of taking a snapshot or the image
         // save request is full then ignore.
         if (mCameraDevice == null || mCameraState == SNAPSHOT_IN_PROGRESS
-                || mCameraState == SWITCHING_CAMERA || !mAppController.isShutterEnabled()) {
+                || mCameraState == SWITCHING_CAMERA) {
             return false;
         }
+        setCameraState(SNAPSHOT_IN_PROGRESS);
+
         mCaptureStartTime = System.currentTimeMillis();
 
         mPostViewPictureCallbackTime = 0;
@@ -1293,9 +1300,6 @@
         mJpegRotation = info.getJpegOrientation(orientation);
         mCameraDevice.setJpegOrientation(mJpegRotation);
 
-        // We don't want user to press the button again while taking a
-        // multi-second HDR photo.
-        mAppController.setShutterEnabled(false);
         mCameraDevice.takePicture(mHandler,
                 new ShutterCallback(!animateBefore),
                 mRawPictureCallback, mPostViewPictureCallback,
@@ -1304,7 +1308,6 @@
         mNamedImages.nameNewImage(mCaptureStartTime);
 
         mFaceDetectionStarted = false;
-        setCameraState(SNAPSHOT_IN_PROGRESS);
         return true;
     }
 
@@ -1498,7 +1501,8 @@
     @Override
     public void onShutterButtonClick() {
         if (mPaused || (mCameraState == SWITCHING_CAMERA)
-                || (mCameraState == PREVIEW_STOPPED)) {
+                || (mCameraState == PREVIEW_STOPPED)
+                || !mAppController.isShutterEnabled()) {
             mVolumeButtonClickedFlag = false;
             return;
         }
@@ -1513,6 +1517,8 @@
         Log.d(TAG, "onShutterButtonClick: mCameraState=" + mCameraState +
                 " mVolumeButtonClickedFlag=" + mVolumeButtonClickedFlag);
 
+        mAppController.setShutterEnabled(false);
+
         int countDownDuration = mActivity.getSettingsManager()
             .getInteger(SettingsManager.SCOPE_GLOBAL, Keys.KEY_COUNTDOWN_DURATION);
         mTimerDuration = countDownDuration;
diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java
index ce53dc2..a99fcb4 100644
--- a/src/com/android/camera/VideoModule.java
+++ b/src/com/android/camera/VideoModule.java
@@ -596,6 +596,7 @@
         mMeteringAreaSupported =
                 mCameraCapabilities.supports(CameraCapabilities.Feature.METERING_AREA);
         readVideoPreferences();
+        updateDesiredPreviewSize();
         resizeForPreviewAspectRatio();
         initializeFocusManager();
         // TODO: Having focus overlay manager caching the parameters is prone to error,
@@ -765,17 +766,28 @@
         }
         mProfile = CamcorderProfile.get(mCameraId, quality);
         mPreferenceRead = true;
+    }
+
+    /**
+     * Calculates and sets local class variables for Desired Preview sizes.
+     * This function should be called after every change in preview camera
+     * resolution and/or before the preview starts. Note that these values still
+     * need to be pushed to the CameraSettings to actually change the preview
+     * resolution.  Does nothing when camera pointer is null.
+     */
+    private void updateDesiredPreviewSize() {
         if (mCameraDevice == null) {
             return;
         }
+
         mCameraSettings = mCameraDevice.getSettings();
         Point desiredPreviewSize = getDesiredPreviewSize(mAppController.getAndroidContext(),
                 mCameraSettings, mCameraCapabilities, mProfile, mUI.getPreviewScreenSize());
         mDesiredPreviewWidth = desiredPreviewSize.x;
         mDesiredPreviewHeight = desiredPreviewSize.y;
         mUI.setPreviewSize(mDesiredPreviewWidth, mDesiredPreviewHeight);
-        Log.v(TAG, "mDesiredPreviewWidth=" + mDesiredPreviewWidth +
-                ". mDesiredPreviewHeight=" + mDesiredPreviewHeight);
+        Log.v(TAG, "Updated DesiredPreview=" + mDesiredPreviewWidth + "x"
+                + mDesiredPreviewHeight);
     }
 
     @TargetApi(Build.VERSION_CODES.HONEYCOMB)
@@ -787,7 +799,9 @@
      * com.android.camera.cameradevice.CameraCapabilities#getPreferredPreviewSizeForVideo()}
      * but also considers the current preview area size on screen and make sure
      * the final preview size will not be smaller than 1/2 of the current
-     * on screen preview area in terms of their short sides.</p>
+     * on screen preview area in terms of their short sides.  This function has
+     * highest priority of WYSIWYG, 1:1 matching as its best match, even if
+     * there's a larger preview that meets the condition above. </p>
      *
      * @return The preferred preview size or {@code null} if the camera is not
      *         opened yet.
@@ -817,6 +831,19 @@
                 it.remove();
             }
         }
+
+        // Take highest priority for WYSIWYG when the preview exactly matches
+        // video frame size.  The variable sizes is assumed to be filtered
+        // for sizes beyond the UI size.
+        for (Size size : sizes) {
+            if (size.width() == profile.videoFrameWidth
+                    && size.height() == profile.videoFrameHeight) {
+                Log.v(TAG, "Selected =" + size.width() + "x" + size.height()
+                           + " on WYSIWYG Priority");
+                return new Point(profile.videoFrameWidth, profile.videoFrameHeight);
+            }
+        }
+
         Size optimalSize = CameraUtil.getOptimalPreviewSize(context, sizes,
                 (double) profile.videoFrameWidth / profile.videoFrameHeight);
         return new Point(optimalSize.width(), optimalSize.height());
@@ -1589,6 +1616,9 @@
     private void setCameraParameters() {
         SettingsManager settingsManager = mActivity.getSettingsManager();
 
+        // Update Desired Preview size in case video camera resolution has changed.
+        updateDesiredPreviewSize();
+
         mCameraSettings.setPreviewSize(new Size(mDesiredPreviewWidth, mDesiredPreviewHeight));
         // This is required for Samsung SGH-I337 and probably other Samsung S4 versions
         if (Build.BRAND.toLowerCase().contains("samsung")) {
@@ -1623,7 +1653,7 @@
         // here we determine the picture size based on the preview size.
         List<Size> supported = mCameraCapabilities.getSupportedPhotoSizes();
         Size optimalSize = CameraUtil.getOptimalVideoSnapshotPictureSize(supported,
-                (double) mDesiredPreviewWidth / mDesiredPreviewHeight);
+                mDesiredPreviewWidth, mDesiredPreviewHeight);
         Size original = new Size(mCameraSettings.getCurrentPhotoSize());
         if (!original.equals(optimalSize)) {
             mCameraSettings.setPhotoSize(optimalSize);
diff --git a/src/com/android/camera/data/CameraDataAdapter.java b/src/com/android/camera/data/CameraDataAdapter.java
index 19ae6f6..721b213 100644
--- a/src/com/android/camera/data/CameraDataAdapter.java
+++ b/src/com/android/camera/data/CameraDataAdapter.java
@@ -20,7 +20,6 @@
 import android.content.Context;
 import android.net.Uri;
 import android.os.AsyncTask;
-import android.os.Handler;
 import android.view.View;
 
 import com.android.camera.Storage;
@@ -41,7 +40,6 @@
     private static final int DEFAULT_DECODE_SIZE = 1600;
 
     private final Context mContext;
-    private final Handler mCallbackHandler;
 
     private LocalDataList mImages;
 
@@ -55,9 +53,8 @@
 
     private LocalData mLocalDataToDelete;
 
-    public CameraDataAdapter(Context context, Handler callbackHandler, int placeholderResource) {
+    public CameraDataAdapter(Context context, int placeholderResource) {
         mContext = context;
-        mCallbackHandler = callbackHandler;
         mImages = new LocalDataList();
         mPlaceHolderResourceId = placeholderResource;
     }
@@ -147,17 +144,10 @@
     }
 
     @Override
-    public void setListener(final Listener listener) {
+    public void setListener(Listener listener) {
         mListener = listener;
         if (mImages.size() != 0) {
-            mCallbackHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    if (listener != null) {
-                        listener.onDataLoaded();
-                    }
-                }
-            });
+            mListener.onDataLoaded();
         }
     }
 
@@ -170,8 +160,8 @@
     }
 
     @Override
-    public void removeData(final int dataID) {
-        final LocalData d = mImages.remove(dataID);
+    public void removeData(int dataID) {
+        LocalData d = mImages.remove(dataID);
         if (d == null) {
             return;
         }
@@ -179,14 +169,7 @@
         // Delete previously removed data first.
         executeDeletion();
         mLocalDataToDelete = d;
-        mCallbackHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                if (mListener != null) {
-                    mListener.onDataRemoved(dataID, d);
-                }
-            }
-        });
+        mListener.onDataRemoved(dataID, d);
     }
 
     @Override
@@ -248,19 +231,12 @@
             return;
         }
 
-        final LocalData data = mImages.get(pos);
+        LocalData data = mImages.get(pos);
         LocalData refreshedData = data.refresh(mContext);
 
         // Refresh failed. Probably removed already.
-        if (refreshedData == null) {
-            mCallbackHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    if (mListener != null) {
-                        mListener.onDataRemoved(pos, data);
-                    }
-                }
-            });
+        if (refreshedData == null && mListener != null) {
+            mListener.onDataRemoved(pos, data);
             return;
         }
         updateData(pos, refreshedData);
@@ -269,27 +245,22 @@
     @Override
     public void updateData(final int pos, LocalData data) {
         mImages.set(pos, data);
-        mCallbackHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                if (mListener != null) {
-                    mListener.onDataUpdated(new UpdateReporter() {
-                        @Override
-                        public boolean isDataRemoved(int dataID) {
-                            return false;
-                        }
-
-                        @Override
-                        public boolean isDataUpdated(int dataID) {
-                            return (dataID == pos);
-                        }
-                    });
+        if (mListener != null) {
+            mListener.onDataUpdated(new UpdateReporter() {
+                @Override
+                public boolean isDataRemoved(int dataID) {
+                    return false;
                 }
-            }
-        });
+
+                @Override
+                public boolean isDataUpdated(int dataID) {
+                    return (dataID == pos);
+                }
+            });
+        }
     }
 
-    private void insertData(final LocalData data) {
+    private void insertData(LocalData data) {
         // Since this function is mostly for adding the newest data,
         // a simple linear search should yield the best performance over a
         // binary search.
@@ -300,15 +271,9 @@
             ;
         }
         mImages.add(pos, data);
-        final int fpos = pos;
-        mCallbackHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                if (mListener != null) {
-                    mListener.onDataInserted(fpos, data);
-                }
-            }
-        });
+        if (mListener != null) {
+            mListener.onDataInserted(pos, data);
+        }
     }
 
     /** Update all the data */
@@ -317,14 +282,9 @@
             return;
         }
         mImages = list;
-        mCallbackHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                if (mListener != null) {
-                    mListener.onDataLoaded();
-                }
-            }
-        });
+        if (mListener != null) {
+            mListener.onDataLoaded();
+        }
     }
 
     @Override
@@ -361,7 +321,7 @@
         return getTotalNumber();
     }
 
-    private class LoadNewPhotosTask extends AsyncTask<ContentResolver, Void, Void> {
+    private class LoadNewPhotosTask extends AsyncTask<ContentResolver, Void, List<LocalData>> {
 
         private final long mMinPhotoId;
 
@@ -372,29 +332,34 @@
         /**
          * Loads any new photos added to our storage directory since our last query.
          * @param contentResolvers {@link android.content.ContentResolver} to load data.
+         * @return An {@link java.util.ArrayList} containing any new data.
          */
         @Override
-        protected Void doInBackground(ContentResolver... contentResolvers) {
+        protected List<LocalData> doInBackground(ContentResolver... contentResolvers) {
             if (mMinPhotoId != LocalMediaData.QUERY_ALL_MEDIA_ID) {
                 final ContentResolver cr = contentResolvers[0];
-                List<LocalData> newPhotoData = LocalMediaData.PhotoData.query(cr, LocalMediaData.PhotoData.CONTENT_URI,
+                return LocalMediaData.PhotoData.query(cr, LocalMediaData.PhotoData.CONTENT_URI,
                         mMinPhotoId);
-                if (!newPhotoData.isEmpty()) {
-                    LocalData newestPhoto = newPhotoData.get(0);
-                    // We may overlap with another load task or a query task, in which case we want
-                    // to be sure we never decrement the oldest seen id.
-                    mLastPhotoId = Math.max(mLastPhotoId, newestPhoto.getContentId());
-                }
-                // We may add data that is already present, but if we do, it will be deduped in addData.
-                // addData does not dedupe session items, so we ignore them here
-                for (LocalData localData : newPhotoData) {
-                    Uri sessionUri = Storage.getSessionUriFromContentUri(localData.getUri());
-                    if (sessionUri == null) {
-                        addData(localData);
-                    }
+            }
+            return new ArrayList<LocalData>(0);
+        }
+
+        @Override
+        protected void onPostExecute(List<LocalData> newPhotoData) {
+            if (!newPhotoData.isEmpty()) {
+                LocalData newestPhoto = newPhotoData.get(0);
+                // We may overlap with another load task or a query task, in which case we want
+                // to be sure we never decrement the oldest seen id.
+                mLastPhotoId = Math.max(mLastPhotoId, newestPhoto.getContentId());
+            }
+            // We may add data that is already present, but if we do, it will be deduped in addData.
+            // addData does not dedupe session items, so we ignore them here
+            for (LocalData localData : newPhotoData) {
+                Uri sessionUri = Storage.getSessionUriFromContentUri(localData.getUri());
+                if (sessionUri == null) {
+                    addData(localData);
                 }
             }
-            return null;
         }
     }
 
diff --git a/src/com/android/camera/settings/CameraSettingsActivity.java b/src/com/android/camera/settings/CameraSettingsActivity.java
index f09f33b..db9c62c 100644
--- a/src/com/android/camera/settings/CameraSettingsActivity.java
+++ b/src/com/android/camera/settings/CameraSettingsActivity.java
@@ -50,6 +50,13 @@
  * Provides the settings UI for the Camera app.
  */
 public class CameraSettingsActivity extends FragmentActivity {
+    /**
+     * Used to denote a subsection of the preference tree to display in the
+     * Fragment. For instance, if 'Advanced' key is provided, the advanced
+     * preference section will be treated as the root for display. This is used
+     * to enable activity transitions between preference sections, and allows
+     * back/up stack to operate correctly.
+     */
     public static final String PREF_SCREEN_EXTRA = "pref_screen_extra";
 
     @Override
@@ -61,7 +68,10 @@
         actionBar.setTitle(R.string.mode_settings);
 
         String prefKey = getIntent().getStringExtra(PREF_SCREEN_EXTRA);
-        CameraSettingsFragment dialog = new CameraSettingsFragment(prefKey);
+        CameraSettingsFragment dialog = new CameraSettingsFragment();
+        Bundle bundle = new Bundle(1);
+        bundle.putString(PREF_SCREEN_EXTRA, prefKey);
+        dialog.setArguments(bundle);
         getFragmentManager().beginTransaction().replace(android.R.id.content, dialog).commit();
     }
 
@@ -85,7 +95,7 @@
         private static DecimalFormat sMegaPixelFormat = new DecimalFormat("##0.0");
         private String[] mCamcorderProfileNames;
         private CameraDeviceInfo mInfos;
-        private final String mPrefKey;
+        private String mPrefKey;
         private boolean mGetSubPrefAsRoot = true;
 
         // Selected resolutions for the different cameras and sizes.
@@ -96,13 +106,13 @@
         private SelectedVideoQualities mVideoQualitiesBack;
         private SelectedVideoQualities mVideoQualitiesFront;
 
-        public CameraSettingsFragment(String prefKey) {
-            mPrefKey = prefKey;
-        }
-
         @Override
         public void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
+            Bundle arguments = getArguments();
+            if (arguments != null) {
+                mPrefKey = arguments.getString(PREF_SCREEN_EXTRA);
+            }
             Context context = this.getActivity().getApplicationContext();
             addPreferencesFromResource(R.xml.camera_preferences);
 
diff --git a/src/com/android/camera/util/CameraUtil.java b/src/com/android/camera/util/CameraUtil.java
index b415901..658e73b 100644
--- a/src/com/android/camera/util/CameraUtil.java
+++ b/src/com/android/camera/util/CameraUtil.java
@@ -563,12 +563,24 @@
                 }
             }
         }
+
         return optimalSizeIndex;
     }
 
-    /** Returns the largest picture size which matches the given aspect ratio. */
+    /**
+     * Returns the largest picture size which matches the given aspect ratio,
+     * except for the special WYSIWYG case where the picture size exactly matches
+     * the target size.
+     *
+     * @param sizes        a list of candidate sizes, available for use
+     * @param targetWidth  the ideal width of the video snapshot
+     * @param targetHeight the ideal height of the video snapshot
+     * @return the Optimal Video Snapshot Picture Size
+     */
     public static com.android.ex.camera2.portability.Size getOptimalVideoSnapshotPictureSize(
-            List<com.android.ex.camera2.portability.Size> sizes, double targetRatio) {
+            List<com.android.ex.camera2.portability.Size> sizes, int targetWidth,
+            int targetHeight) {
+
         // Use a very small tolerance because we want an exact match.
         final double ASPECT_TOLERANCE = 0.001;
         if (sizes == null) {
@@ -577,7 +589,17 @@
 
         com.android.ex.camera2.portability.Size optimalSize = null;
 
+        //  WYSIWYG Override
+        //  We assume that physical display constraints have already been
+        //  imposed on the variables sizes
+        for (com.android.ex.camera2.portability.Size size : sizes) {
+            if (size.height() == targetHeight && size.width() == targetWidth) {
+                return size;
+            }
+        }
+
         // Try to find a size matches aspect ratio and has the largest width
+        final double targetRatio = (double) targetWidth / targetHeight;
         for (com.android.ex.camera2.portability.Size size : sizes) {
             double ratio = (double) size.width() / size.height();
             if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) {
diff --git a/src/com/android/camera/util/QuickActivity.java b/src/com/android/camera/util/QuickActivity.java
index 965b541..039d8fc 100644
--- a/src/com/android/camera/util/QuickActivity.java
+++ b/src/com/android/camera/util/QuickActivity.java
@@ -179,7 +179,7 @@
     private boolean delayOnResumeOnStart() {
         String action = getIntent().getAction();
         boolean isSecureLockscreenCamera =
-                action.equals(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE);
+                MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE.equals(action);
         return isSecureLockscreenCamera;
     }
 
diff --git a/src_pd/com/android/camera/util/UsageStatistics.java b/src_pd/com/android/camera/util/UsageStatistics.java
index d68dec9..6c208de 100644
--- a/src_pd/com/android/camera/util/UsageStatistics.java
+++ b/src_pd/com/android/camera/util/UsageStatistics.java
@@ -26,6 +26,7 @@
 
 public class UsageStatistics {
     public static final long VIEW_TIMEOUT_MILLIS = 0;
+    public static final int NONE = -1;
 
     private static UsageStatistics sInstance;
 
@@ -66,7 +67,7 @@
                                       Boolean volumeButtonShutter) {
     }
 
-    public void cameraFailure(int cause, String info) {
+    public void cameraFailure(int cause, String info, int agentAction, int agentState) {
     }
 
     public void changeScreen(int newScreen, Integer interactionCause) {
diff --git a/src_pd/com/google/common/logging/eventprotos.java b/src_pd/com/google/common/logging/eventprotos.java
index afb7eb3..292d2a6 100644
--- a/src_pd/com/google/common/logging/eventprotos.java
+++ b/src_pd/com/google/common/logging/eventprotos.java
@@ -54,6 +54,8 @@
             public static final int SECURITY = 10000;
             public static final int OPEN_FAILURE = 10000;
             public static final int RECONNECT_FAILURE = 10000;
+            public static final int API_RUNTIME_EXCEPTION = 10000;
+            public static final int API_TIMEOUT = 10000;
         }
     }