Merge "Some debugging support." into gingerbread
diff --git a/api/current.xml b/api/current.xml
index 956f2b8..4a81b42 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -947,6 +947,17 @@
  visibility="public"
 >
 </field>
+<field name="SET_ALARM"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;com.android.alarm.permission.SET_ALARM&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="SET_ALWAYS_FINISH"
  type="java.lang.String"
  transient="false"
@@ -131718,6 +131729,67 @@
 </package>
 <package name="android.provider"
 >
+<class name="AlarmClock"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="AlarmClock"
+ type="android.provider.AlarmClock"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<field name="ACTION_SET_ALARM"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.intent.action.SET_ALARM&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_HOUR"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.intent.extra.alarm.HOUR&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_MESSAGE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.intent.extra.alarm.MESSAGE&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_MINUTES"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.intent.extra.alarm.MINUTES&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
 <interface name="BaseColumns"
  abstract="true"
  static="false"
diff --git a/core/java/android/provider/AlarmClock.java b/core/java/android/provider/AlarmClock.java
new file mode 100644
index 0000000..b93dfd8
--- /dev/null
+++ b/core/java/android/provider/AlarmClock.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.provider;
+
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+
+/**
+ * The AlarmClock provider contains an Intent action and extras that can be used
+ * to start an Activity to set a new alarm in an alarm clock application.
+ *
+ * Applications that wish to receive the ACTION_SET_ALARM Intent should create
+ * an activity to handle the Intent that requires the permission
+ * com.android.alarm.permission.SET_ALARM.  Applications that wish to create a
+ * new alarm should use
+ * {@link android.content.Context#startActivity Context.startActivity()} so that
+ * the user has the option of choosing which alarm clock application to use.
+ */
+public final class AlarmClock {
+    /**
+     * Activity Action: Set an alarm.
+     * <p>
+     * Input: Nothing.
+     * <p>
+     * Output: Nothing.
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_SET_ALARM = "android.intent.action.SET_ALARM";
+
+    /**
+     * Activity Extra: Provide a custom message for the alarm.
+     * <p>
+     * This can be passed as an extra field in the Intent created with
+     * ACTION_SET_ALARM.
+     */
+    public static final String EXTRA_MESSAGE = "android.intent.extra.alarm.MESSAGE";
+
+    /**
+     * Activity Extra: The hour of the alarm being set.
+     * <p>
+     * This value can be passed as an extra field to the Intent created with
+     * ACTION_SET_ALARM.  If it is not provided, the behavior is undefined and
+     * is up to the application.  The value is an integer and ranges from 0 to
+     * 23.
+     */
+    public static final String EXTRA_HOUR = "android.intent.extra.alarm.HOUR";
+
+    /**
+     * Activity Extra: The minutes of the alarm being set.
+     * <p>
+     * This value can be passed as an extra field to the Intent created with
+     * ACTION_SET_ALARM.  If it is not provided, the behavior is undefined and
+     * is up to the application.  The value is an integer and ranges from 0 to
+     * 59.
+     */
+    public static final String EXTRA_MINUTES = "android.intent.extra.alarm.MINUTES";
+}
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 9d215b7..8409adc 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -252,21 +252,23 @@
     lpJniStorage->mCallbackData.audioTrack_ref = env->NewGlobalRef(weak_this);
     
     lpJniStorage->mStreamType = atStreamType;
-    
-    jint* nSession = NULL;
-    if (jSession) {
-        nSession = (jint *) env->GetPrimitiveArrayCritical(jSession, NULL);
-        if (nSession == NULL) {
-            LOGE("Error creating AudioTrack: Error retrieving session id pointer");
-            delete lpJniStorage;
-            return AUDIOTRACK_ERROR;
-        }
-    } else {
+
+    if (jSession == NULL) {
         LOGE("Error creating AudioTrack: invalid session ID pointer");
         delete lpJniStorage;
         return AUDIOTRACK_ERROR;
     }
 
+    jint* nSession = (jint *) env->GetPrimitiveArrayCritical(jSession, NULL);
+    if (nSession == NULL) {
+        LOGE("Error creating AudioTrack: Error retrieving session id pointer");
+        delete lpJniStorage;
+        return AUDIOTRACK_ERROR;
+    }
+    int sessionId = nSession[0];
+    env->ReleasePrimitiveArrayCritical(jSession, nSession, 0);
+    nSession = NULL;
+
     // create the native AudioTrack object
     AudioTrack* lpTrack = new AudioTrack();
     if (lpTrack == NULL) {
@@ -288,7 +290,7 @@
             0,// notificationFrames == 0 since not using EVENT_MORE_DATA to feed the AudioTrack
             0,// shared mem
             true,// thread can call Java
-            nSession[0]);// audio session ID
+            sessionId);// audio session ID
             
     } else if (memoryMode == javaAudioTrackFields.MODE_STATIC) {
         // AudioTrack is using shared memory
@@ -309,7 +311,7 @@
             0,// notificationFrames == 0 since not using EVENT_MORE_DATA to feed the AudioTrack 
             lpJniStorage->mMemBase,// shared mem
             true,// thread can call Java
-            nSession[0]);// audio session ID
+            sessionId);// audio session ID
     }
 
     if (lpTrack->initCheck() != NO_ERROR) {
@@ -317,9 +319,13 @@
         goto native_init_failure;
     }
 
+    nSession = (jint *) env->GetPrimitiveArrayCritical(jSession, NULL);
+    if (nSession == NULL) {
+        LOGE("Error creating AudioTrack: Error retrieving session id pointer");
+        goto native_init_failure;
+    }
     // read the audio session ID back from AudioTrack in case we create a new session
     nSession[0] = lpTrack->getSessionId();
-
     env->ReleasePrimitiveArrayCritical(jSession, nSession, 0);
     nSession = NULL;
 
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index ab0ff3f..68a5a14 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -242,6 +242,14 @@
         android:description="@string/permdesc_writeHistoryBookmarks"
         android:protectionLevel="dangerous" />
 
+    <!-- Allows an application to broadcast an Intent to set an alarm for the
+         user. -->
+    <permission android:name="com.android.alarm.permission.SET_ALARM"
+        android:permissionGroup="android.permission-group.PERSONAL_INFO"
+        android:label="@string/permlab_setAlarm"
+        android:description="@string/permdesc_setAlarm"
+        android:protectionLevel="normal" />
+
     <!-- ======================================= -->
     <!-- Permissions for accessing location info -->
     <!-- ======================================= -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 808b371..ebccfb6 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1619,6 +1619,15 @@
 
     <!-- Title of an application permission, listed so the user can choose whether
         they want to allow the application to do this. -->
+    <string name="permlab_setAlarm">set alarm in alarm clock</string>
+    <!-- Description of an application permission, listed so the user can choose whether
+        they want to allow the application to do this. -->
+    <string name="permdesc_setAlarm">Allows the application to set an alarm in
+      an installed alarm clock application. Some alarm clock applications may
+      not implement this feature.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether
+        they want to allow the application to do this. -->
     <string name="permlab_writeGeolocationPermissions">Modify Browser geolocation permissions</string>
     <!-- Description of an application permission, listed so the user can choose whether
         they want to allow the application to do this. -->
diff --git a/include/utils/ZipFileRO.h b/include/utils/ZipFileRO.h
index 97d31f4..9668bde 100644
--- a/include/utils/ZipFileRO.h
+++ b/include/utils/ZipFileRO.h
@@ -24,8 +24,9 @@
 #ifndef __LIBS_ZIPFILERO_H
 #define __LIBS_ZIPFILERO_H
 
-#include "Errors.h"
-#include "FileMap.h"
+#include <utils/Errors.h>
+#include <utils/FileMap.h>
+#include <utils/threads.h>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -211,6 +212,9 @@
     /* open Zip archive */
     int         mFd;
 
+    /* Lock for handling the file descriptor (seeks, etc) */
+    mutable Mutex mFdLock;
+
     /* zip file name */
     char*       mFileName;
 
diff --git a/libs/utils/ZipFileRO.cpp b/libs/utils/ZipFileRO.cpp
index 2d53136..9fcae72 100644
--- a/libs/utils/ZipFileRO.cpp
+++ b/libs/utils/ZipFileRO.cpp
@@ -22,6 +22,7 @@
 #include <utils/ZipFileRO.h>
 #include <utils/Log.h>
 #include <utils/misc.h>
+#include <utils/threads.h>
 
 #include <zlib.h>
 
@@ -195,7 +196,7 @@
             free(scanBuf);
             return false;
         } else if (header != kLFHSignature) {
-            LOGV("Not a Zip archive (found 0x%08x)\n", val);
+            LOGV("Not a Zip archive (found 0x%08x)\n", header);
             free(scanBuf);
             return false;
         }
@@ -496,15 +497,21 @@
         }
 
         unsigned char lfhBuf[kLFHLen];
-        if (lseek(mFd, localHdrOffset, SEEK_SET) != localHdrOffset) {
-            LOGW("failed seeking to lfh at offset %ld\n", localHdrOffset);
-            return false;
-        }
-        ssize_t actual =
-            TEMP_FAILURE_RETRY(read(mFd, lfhBuf, sizeof(lfhBuf)));
-        if (actual != sizeof(lfhBuf)) {
-            LOGW("failed reading lfh from offset %ld\n", localHdrOffset);
-            return false;
+
+        {
+            AutoMutex _l(mFdLock);
+
+            if (lseek(mFd, localHdrOffset, SEEK_SET) != localHdrOffset) {
+                LOGW("failed seeking to lfh at offset %ld\n", localHdrOffset);
+                return false;
+            }
+
+            ssize_t actual =
+                TEMP_FAILURE_RETRY(read(mFd, lfhBuf, sizeof(lfhBuf)));
+            if (actual != sizeof(lfhBuf)) {
+                LOGW("failed reading lfh from offset %ld\n", localHdrOffset);
+                return false;
+            }
         }
 
         if (get4LE(lfhBuf) != kLFHSignature) {
@@ -636,7 +643,7 @@
         memcpy(buffer, ptr, uncompLen);
     } else {
         if (!inflateBuffer(buffer, ptr, uncompLen, compLen))
-            goto bail;
+            goto unmap;
     }
 
     if (compLen > kSequentialMin)
@@ -644,6 +651,8 @@
 
     result = true;
 
+unmap:
+    file->release();
 bail:
     return result;
 }
@@ -667,7 +676,7 @@
 
     getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL);
 
-    const FileMap* file = createEntryFileMap(entry);
+    FileMap* file = createEntryFileMap(entry);
     if (file == NULL) {
         goto bail;
     }
@@ -678,21 +687,23 @@
         ssize_t actual = write(fd, ptr, uncompLen);
         if (actual < 0) {
             LOGE("Write failed: %s\n", strerror(errno));
-            goto bail;
+            goto unmap;
         } else if ((size_t) actual != uncompLen) {
             LOGE("Partial write during uncompress (%zd of %zd)\n",
                 (size_t)actual, (size_t)uncompLen);
-            goto bail;
+            goto unmap;
         } else {
             LOGI("+++ successful write\n");
         }
     } else {
         if (!inflateBuffer(fd, ptr, uncompLen, compLen))
-            goto bail;
+            goto unmap;
     }
 
     result = true;
 
+unmap:
+    file->release();
 bail:
     return result;
 }
diff --git a/media/jni/audioeffect/android_media_AudioEffect.cpp b/media/jni/audioeffect/android_media_AudioEffect.cpp
index b16372d..cb2f0f9 100644
--- a/media/jni/audioeffect/android_media_AudioEffect.cpp
+++ b/media/jni/audioeffect/android_media_AudioEffect.cpp
@@ -304,14 +304,7 @@
             lpJniStorage->mCallbackData.audioEffect_class,
             &lpJniStorage->mCallbackData);
 
-    if (jId) {
-        nId = (jint *) env->GetPrimitiveArrayCritical(jId, NULL);
-        if (nId == NULL) {
-            LOGE("setup: Error retrieving id pointer");
-            lStatus = AUDIOEFFECT_ERROR_BAD_VALUE;
-            goto setup_failure;
-        }
-    } else {
+    if (jId == NULL) {
         LOGE("setup: NULL java array for id pointer");
         lStatus = AUDIOEFFECT_ERROR_BAD_VALUE;
         goto setup_failure;
@@ -336,8 +329,13 @@
         goto setup_failure;
     }
 
+    nId = (jint *) env->GetPrimitiveArrayCritical(jId, NULL);
+    if (nId == NULL) {
+        LOGE("setup: Error retrieving id pointer");
+        lStatus = AUDIOEFFECT_ERROR_BAD_VALUE;
+        goto setup_failure;
+    }
     nId[0] = lpAudioEffect->id();
-
     env->ReleasePrimitiveArrayCritical(jId, nId, 0);
     nId = NULL;
 
diff --git a/media/jni/audioeffect/android_media_Visualizer.cpp b/media/jni/audioeffect/android_media_Visualizer.cpp
index 7b271ce..57cafd4 100644
--- a/media/jni/audioeffect/android_media_Visualizer.cpp
+++ b/media/jni/audioeffect/android_media_Visualizer.cpp
@@ -246,14 +246,7 @@
             lpJniStorage->mCallbackData.visualizer_class,
             &lpJniStorage->mCallbackData);
 
-    if (jId) {
-        nId = (jint *) env->GetPrimitiveArrayCritical(jId, NULL);
-        if (nId == NULL) {
-            LOGE("setup: Error retrieving id pointer");
-            lStatus = VISUALIZER_ERROR_BAD_VALUE;
-            goto setup_failure;
-        }
-    } else {
+    if (jId == NULL) {
         LOGE("setup: NULL java array for id pointer");
         lStatus = VISUALIZER_ERROR_BAD_VALUE;
         goto setup_failure;
@@ -275,8 +268,13 @@
         goto setup_failure;
     }
 
+    nId = (jint *) env->GetPrimitiveArrayCritical(jId, NULL);
+    if (nId == NULL) {
+        LOGE("setup: Error retrieving id pointer");
+        lStatus = VISUALIZER_ERROR_BAD_VALUE;
+        goto setup_failure;
+    }
     nId[0] = lpVisualizer->id();
-
     env->ReleasePrimitiveArrayCritical(jId, nId, 0);
     nId = NULL;
 
@@ -424,7 +422,6 @@
     jint status = translateError(lpVisualizer->getWaveForm((uint8_t *)nWaveform));
 
     env->ReleasePrimitiveArrayCritical(jWaveform, nWaveform, 0);
-
     return status;
 }
 
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index ade93da..6e2bfdb 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -327,10 +327,7 @@
         try {
             final String value = c.moveToNext() ? c.getString(0) : null;
             if (value == null) {
-                final SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
-                String serial = SystemProperties.get("ro.serialno", "");
-                random.setSeed(
-                    (serial + System.nanoTime() + new SecureRandom().nextLong()).getBytes());
+                final SecureRandom random = new SecureRandom();
                 final String newAndroidIdValue = Long.toHexString(random.nextLong());
                 Log.d(TAG, "Generated and saved new ANDROID_ID [" + newAndroidIdValue + "]");
                 final ContentValues values = new ContentValues();
@@ -342,8 +339,6 @@
                 }
             }
             return true;
-        } catch (NoSuchAlgorithmException e) {
-            return false;
         } finally {
             c.close();
         }
diff --git a/services/java/com/android/server/sip/SipSessionGroup.java b/services/java/com/android/server/sip/SipSessionGroup.java
index 66a2c05..fa3f64a 100644
--- a/services/java/com/android/server/sip/SipSessionGroup.java
+++ b/services/java/com/android/server/sip/SipSessionGroup.java
@@ -84,7 +84,7 @@
     private static final String ANONYMOUS = "anonymous";
     private static final String SERVER_ERROR_PREFIX = "Response: ";
     private static final int EXPIRY_TIME = 3600; // in seconds
-    private static final int CANCEL_CALL_TIMER = 5; // in seconds
+    private static final int CANCEL_CALL_TIMER = 3; // in seconds
 
     private static final EventObject DEREGISTER = new EventObject("Deregister");
     private static final EventObject END_CALL = new EventObject("End call");
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhone.java b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
index 372acc2..45e6ccd 100755
--- a/telephony/java/com/android/internal/telephony/sip/SipPhone.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
@@ -74,7 +74,9 @@
 public class SipPhone extends SipPhoneBase {
     private static final String LOG_TAG = "SipPhone";
     private static final boolean LOCAL_DEBUG = true;
-    private static final int SESSION_TIMEOUT = 8; // in seconds
+    private static final int TIMEOUT_MAKE_CALL = 15; // in seconds
+    private static final int TIMEOUT_ANSWER_CALL = 8; // in seconds
+    private static final int TIMEOUT_HOLD_CALL = 15; // in seconds
 
     // A call that is ringing or (call) waiting
     private SipCall ringingCall = new SipCall();
@@ -690,7 +692,7 @@
 
         void acceptCall() throws CallStateException {
             try {
-                mSipAudioCall.answerCall(SESSION_TIMEOUT);
+                mSipAudioCall.answerCall(TIMEOUT_ANSWER_CALL);
             } catch (SipException e) {
                 throw new CallStateException("acceptCall(): " + e);
             }
@@ -708,7 +710,7 @@
         void dial() throws SipException {
             setState(Call.State.DIALING);
             mSipAudioCall = mSipManager.makeAudioCall(mProfile, mPeer, null,
-                    SESSION_TIMEOUT);
+                    TIMEOUT_MAKE_CALL);
             mSipAudioCall.setRingbackToneEnabled(false);
             mSipAudioCall.setListener(mAdapter);
         }
@@ -716,7 +718,7 @@
         void hold() throws CallStateException {
             setState(Call.State.HOLDING);
             try {
-                mSipAudioCall.holdCall(SESSION_TIMEOUT);
+                mSipAudioCall.holdCall(TIMEOUT_HOLD_CALL);
             } catch (SipException e) {
                 throw new CallStateException("hold(): " + e);
             }
@@ -726,7 +728,7 @@
             mSipAudioCall.setAudioGroup(audioGroup);
             setState(Call.State.ACTIVE);
             try {
-                mSipAudioCall.continueCall(SESSION_TIMEOUT);
+                mSipAudioCall.continueCall(TIMEOUT_HOLD_CALL);
             } catch (SipException e) {
                 throw new CallStateException("unhold(): " + e);
             }