Merge "Fix RecentApps to properly load new thumbnails."
diff --git a/api/current.xml b/api/current.xml
index a866669..dde924a 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -20328,7 +20328,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="value" type="android.view.animation.Interpolator">
+<parameter name="value" type="android.animation.TimeInterpolator">
</parameter>
</method>
<method name="setStartDelay"
@@ -20678,7 +20678,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="interpolator" type="android.view.animation.Interpolator">
+<parameter name="interpolator" type="android.animation.TimeInterpolator">
</parameter>
</method>
<method name="setStartDelay"
@@ -20981,7 +20981,7 @@
>
</method>
<method name="getInterpolator"
- return="android.view.animation.Interpolator"
+ return="android.animation.TimeInterpolator"
abstract="false"
native="false"
synchronized="false"
@@ -21036,7 +21036,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="interpolator" type="android.view.animation.Interpolator">
+<parameter name="interpolator" type="android.animation.TimeInterpolator">
</parameter>
</method>
<method name="setValue"
@@ -21124,7 +21124,7 @@
</parameter>
</method>
<method name="getInterpolator"
- return="android.view.animation.Interpolator"
+ return="android.animation.TimeInterpolator"
abstract="false"
native="false"
synchronized="false"
@@ -21271,7 +21271,7 @@
>
<parameter name="transitionType" type="int">
</parameter>
-<parameter name="interpolator" type="android.view.animation.Interpolator">
+<parameter name="interpolator" type="android.animation.TimeInterpolator">
</parameter>
</method>
<method name="setStagger"
@@ -21670,6 +21670,27 @@
</parameter>
</method>
</class>
+<interface name="TimeInterpolator"
+ abstract="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="getInterpolation"
+ return="float"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="input" type="float">
+</parameter>
+</method>
+</interface>
<interface name="TypeEvaluator"
abstract="true"
static="false"
@@ -21794,7 +21815,7 @@
>
</method>
<method name="getInterpolator"
- return="android.view.animation.Interpolator"
+ return="android.animation.TimeInterpolator"
abstract="false"
native="false"
synchronized="false"
@@ -21956,7 +21977,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="value" type="android.view.animation.Interpolator">
+<parameter name="value" type="android.animation.TimeInterpolator">
</parameter>
</method>
<method name="setRepeatCount"
@@ -43986,6 +44007,17 @@
synchronized="false"
static="true"
final="false"
+ deprecated="deprecated"
+ visibility="public"
+>
+</method>
+<method name="getCurrentSyncs"
+ return="java.util.List<android.content.SyncInfo>"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
deprecated="not deprecated"
visibility="public"
>
@@ -54129,6 +54161,34 @@
deprecated="not deprecated"
visibility="public"
>
+<implements name="android.os.Parcelable">
+</implements>
+<method name="describeContents"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="writeToParcel"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="parcel" type="android.os.Parcel">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
<field name="account"
type="android.accounts.Account"
transient="false"
@@ -212417,19 +212477,8 @@
deprecated="not deprecated"
visibility="public"
>
-<method name="getInterpolation"
- return="float"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="input" type="float">
-</parameter>
-</method>
+<implements name="android.animation.TimeInterpolator">
+</implements>
</interface>
<class name="LayoutAnimationController"
extends="java.lang.Object"
@@ -215713,6 +215762,19 @@
<parameter name="id" type="java.lang.String">
</parameter>
</method>
+<method name="showInputMethodAndSubtypeEnabler"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="topId" type="java.lang.String">
+</parameter>
+</method>
<method name="showInputMethodPicker"
return="void"
abstract="false"
@@ -242734,7 +242796,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="t" type="T">
+<parameter name="arg0" type="T">
</parameter>
</method>
</interface>
diff --git a/cmds/app_process/app_main.cpp b/cmds/app_process/app_main.cpp
index 7decf9a..0159edd 100644
--- a/cmds/app_process/app_main.cpp
+++ b/cmds/app_process/app_main.cpp
@@ -171,9 +171,9 @@
runtime.start();
}
} else {
- LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
app_usage();
+ LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
return 10;
}
diff --git a/cmds/stagefright/recordvideo.cpp b/cmds/stagefright/recordvideo.cpp
index 330fbc2..f8eb514 100644
--- a/cmds/stagefright/recordvideo.cpp
+++ b/cmds/stagefright/recordvideo.cpp
@@ -18,12 +18,10 @@
#include <binder/ProcessState.h>
#include <media/stagefright/AudioPlayer.h>
-#include <media/stagefright/FileSource.h>
#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MetaData.h>
-#include <media/stagefright/MediaExtractor.h>
#include <media/stagefright/MPEG4Writer.h>
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/OMXCodec.h>
@@ -31,18 +29,21 @@
using namespace android;
-// print usage showing how to use this utility to record videos
+// Print usage showing how to use this utility to record videos
static void usage(const char *me) {
fprintf(stderr, "usage: %s\n", me);
fprintf(stderr, " -h(elp)\n");
- fprintf(stderr, " -b bit rate in bits per second (default 300000)\n");
- fprintf(stderr, " -c YUV420 color format: [0] semi planar or [1] planar (default 1)\n");
- fprintf(stderr, " -f frame rate in frames per second (default 30)\n");
- fprintf(stderr, " -i I frame interval in seconds (default 1)\n");
- fprintf(stderr, " -n number of frames to be recorded (default 300)\n");
- fprintf(stderr, " -w width in pixels (default 176)\n");
- fprintf(stderr, " -t height in pixels (default 144)\n");
- fprintf(stderr, " -v video codec: [0] AVC [1] M4V [2] H263 (default 0)\n");
+ fprintf(stderr, " -b bit rate in bits per second (default: 300000)\n");
+ fprintf(stderr, " -c YUV420 color format: [0] semi planar or [1] planar (default: 1)\n");
+ fprintf(stderr, " -f frame rate in frames per second (default: 30)\n");
+ fprintf(stderr, " -i I frame interval in seconds (default: 1)\n");
+ fprintf(stderr, " -n number of frames to be recorded (default: 300)\n");
+ fprintf(stderr, " -w width in pixels (default: 176)\n");
+ fprintf(stderr, " -t height in pixels (default: 144)\n");
+ fprintf(stderr, " -l encoder level. see omx il header (default: encoder specific)\n");
+ fprintf(stderr, " -p encoder profile. see omx il header (default: encoder specific)\n");
+ fprintf(stderr, " -v video codec: [0] AVC [1] M4V [2] H263 (default: 0)\n");
+ fprintf(stderr, "The output file is /sdcard/output.mp4\n");
exit(1);
}
@@ -56,6 +57,7 @@
mFrameRate(fps),
mColorFormat(colorFormat),
mSize((width * height * 3) / 2) {
+
mGroup.add_buffer(new MediaBuffer(mSize));
// Check the color format to make sure
@@ -98,8 +100,11 @@
return err;
}
- char x = (char)((double)rand() / RAND_MAX * 255);
- memset((*buffer)->data(), x, mSize);
+ // We don't care about the contents. we just test video encoder
+ // Also, by skipping the content generation, we can return from
+ // read() much faster.
+ //char x = (char)((double)rand() / RAND_MAX * 255);
+ //memset((*buffer)->data(), x, mSize);
(*buffer)->set_range(0, mSize);
(*buffer)->meta_data()->clear();
(*buffer)->meta_data()->setInt64(
@@ -125,38 +130,6 @@
DummySource &operator=(const DummySource &);
};
-sp<MediaSource> createSource(const char *filename) {
- sp<MediaSource> source;
-
- sp<MediaExtractor> extractor =
- MediaExtractor::Create(new FileSource(filename));
- if (extractor == NULL) {
- return NULL;
- }
-
- size_t num_tracks = extractor->countTracks();
-
- sp<MetaData> meta;
- for (size_t i = 0; i < num_tracks; ++i) {
- meta = extractor->getTrackMetaData(i);
- CHECK(meta.get() != NULL);
-
- const char *mime;
- if (!meta->findCString(kKeyMIMEType, &mime)) {
- continue;
- }
-
- if (strncasecmp(mime, "video/", 6)) {
- continue;
- }
-
- source = extractor->getTrack(i);
- break;
- }
-
- return source;
-}
-
enum {
kYUV420SP = 0,
kYUV420P = 1,
@@ -186,12 +159,14 @@
int iFramesIntervalSeconds = 1;
int colorFormat = OMX_COLOR_FormatYUV420Planar;
int nFrames = 300;
+ int level = -1; // Encoder specific default
+ int profile = -1; // Encoder specific default
int codec = 0;
const char *fileName = "/sdcard/output.mp4";
android::ProcessState::self()->startThreadPool();
int res;
- while ((res = getopt(argc, argv, "b:c:f:i:n:w:t:v:o:h")) >= 0) {
+ while ((res = getopt(argc, argv, "b:c:f:i:n:w:t:l:p:v:h")) >= 0) {
switch (res) {
case 'b':
{
@@ -238,6 +213,18 @@
break;
}
+ case 'l':
+ {
+ level = atoi(optarg);
+ break;
+ }
+
+ case 'p':
+ {
+ profile = atoi(optarg);
+ break;
+ }
+
case 'v':
{
codec = atoi(optarg);
@@ -260,7 +247,8 @@
CHECK_EQ(client.connect(), OK);
status_t err = OK;
- sp<MediaSource> decoder = new DummySource(width, height, nFrames, frameRateFps, colorFormat);
+ sp<MediaSource> source =
+ new DummySource(width, height, nFrames, frameRateFps, colorFormat);
sp<MetaData> enc_meta = new MetaData;
switch (codec) {
@@ -282,10 +270,16 @@
enc_meta->setInt32(kKeySliceHeight, height);
enc_meta->setInt32(kKeyIFramesInterval, iFramesIntervalSeconds);
enc_meta->setInt32(kKeyColorFormat, colorFormat);
+ if (level != -1) {
+ enc_meta->setInt32(kKeyVideoLevel, level);
+ }
+ if (profile != -1) {
+ enc_meta->setInt32(kKeyVideoProfile, profile);
+ }
sp<MediaSource> encoder =
OMXCodec::Create(
- client.interface(), enc_meta, true /* createEncoder */, decoder);
+ client.interface(), enc_meta, true /* createEncoder */, source);
sp<MPEG4Writer> writer = new MPEG4Writer(fileName);
writer->addSource(encoder);
@@ -296,7 +290,7 @@
err = writer->stop();
int64_t end = systemTime();
- printf("$\n");
+ fprintf(stderr, "$\n");
client.disconnect();
if (err != OK && err != ERROR_END_OF_STREAM) {
diff --git a/core/java/android/animation/Animator.java b/core/java/android/animation/Animator.java
index 2ada6d6..d3e0797 100644
--- a/core/java/android/animation/Animator.java
+++ b/core/java/android/animation/Animator.java
@@ -16,8 +16,6 @@
package android.animation;
-import android.view.animation.Interpolator;
-
import java.util.ArrayList;
/**
@@ -97,7 +95,7 @@
*
* @param value the interpolator to be used by this animation
*/
- public abstract void setInterpolator(Interpolator value);
+ public abstract void setInterpolator(TimeInterpolator value);
/**
* Returns whether this Animator is currently running (having been started and not yet ended).
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index a8385e4..5de0293 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -16,8 +16,6 @@
package android.animation;
-import android.view.animation.Interpolator;
-
import java.util.ArrayList;
import java.util.HashMap;
@@ -173,13 +171,13 @@
}
/**
- * Sets the Interpolator for all current {@link #getChildAnimations() child animations}
+ * Sets the TimeInterpolator for all current {@link #getChildAnimations() child animations}
* of this AnimatorSet.
*
* @param interpolator the interpolator to be used by each child animation of this AnimatorSet
*/
@Override
- public void setInterpolator(Interpolator interpolator) {
+ public void setInterpolator(TimeInterpolator interpolator) {
for (Node node : mNodes) {
node.animation.setInterpolator(interpolator);
}
diff --git a/core/java/android/animation/Keyframe.java b/core/java/android/animation/Keyframe.java
index 192ba5c..f9a4f3c 100644
--- a/core/java/android/animation/Keyframe.java
+++ b/core/java/android/animation/Keyframe.java
@@ -16,14 +16,12 @@
package android.animation;
-import android.view.animation.Interpolator;
-
/**
* This class holds a time/value pair for an animation. The Keyframe class is used
* by {@link ValueAnimator} to define the values that the animation target will have over the course
* of the animation. As the time proceeds from one keyframe to the other, the value of the
* target object will animate between the value at the previous keyframe and the value at the
- * next keyframe. Each keyframe also holds an option {@link android.view.animation.Interpolator}
+ * next keyframe. Each keyframe also holds an optional {@link TimeInterpolator}
* object, which defines the time interpolation over the intervalue preceding the keyframe.
*/
public class Keyframe implements Cloneable {
@@ -47,7 +45,7 @@
* The optional time interpolator for the interval preceding this keyframe. A null interpolator
* (the default) results in linear interpolation over the interval.
*/
- private Interpolator mInterpolator = null;
+ private TimeInterpolator mInterpolator = null;
/**
* Private constructor, called from the public constructors with the additional
@@ -224,7 +222,7 @@
*
* @return The optional interpolator for this Keyframe.
*/
- public Interpolator getInterpolator() {
+ public TimeInterpolator getInterpolator() {
return mInterpolator;
}
@@ -234,7 +232,7 @@
*
* @return The optional interpolator for this Keyframe.
*/
- public void setInterpolator(Interpolator interpolator) {
+ public void setInterpolator(TimeInterpolator interpolator) {
mInterpolator = interpolator;
}
diff --git a/core/java/android/animation/KeyframeSet.java b/core/java/android/animation/KeyframeSet.java
index af47a15..a24b1fb 100644
--- a/core/java/android/animation/KeyframeSet.java
+++ b/core/java/android/animation/KeyframeSet.java
@@ -18,8 +18,6 @@
import java.util.ArrayList;
-import android.view.animation.Interpolator;
-
/**
* This class holds a collection of Keyframe objects and is called by ValueAnimator to calculate
* values between those keyframes for a given animation. The class internal to the animation
@@ -58,7 +56,7 @@
if (fraction <= 0f) {
final Keyframe prevKeyframe = mKeyframes.get(0);
final Keyframe nextKeyframe = mKeyframes.get(1);
- final Interpolator interpolator = nextKeyframe.getInterpolator();
+ final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
if (interpolator != null) {
fraction = interpolator.getInterpolation(fraction);
}
@@ -69,7 +67,7 @@
} else if (fraction >= 1f) {
final Keyframe prevKeyframe = mKeyframes.get(mNumKeyframes - 2);
final Keyframe nextKeyframe = mKeyframes.get(mNumKeyframes - 1);
- final Interpolator interpolator = nextKeyframe.getInterpolator();
+ final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
if (interpolator != null) {
fraction = interpolator.getInterpolation(fraction);
}
@@ -82,7 +80,7 @@
for (int i = 1; i < mNumKeyframes; ++i) {
Keyframe nextKeyframe = mKeyframes.get(i);
if (fraction < nextKeyframe.getFraction()) {
- final Interpolator interpolator = nextKeyframe.getInterpolator();
+ final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
if (interpolator != null) {
fraction = interpolator.getInterpolation(fraction);
}
diff --git a/core/java/android/animation/LayoutTransition.java b/core/java/android/animation/LayoutTransition.java
index 52f0f16..56ad857 100644
--- a/core/java/android/animation/LayoutTransition.java
+++ b/core/java/android/animation/LayoutTransition.java
@@ -21,7 +21,6 @@
import android.view.ViewTreeObserver;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
-import android.view.animation.Interpolator;
import java.util.ArrayList;
import java.util.HashMap;
@@ -142,10 +141,10 @@
/**
* The default interpolators used for the animations
*/
- private Interpolator mAppearingInterpolator = new AccelerateDecelerateInterpolator();
- private Interpolator mDisappearingInterpolator = new AccelerateDecelerateInterpolator();
- private Interpolator mChangingAppearingInterpolator = new DecelerateInterpolator();
- private Interpolator mChangingDisappearingInterpolator = new DecelerateInterpolator();
+ private TimeInterpolator mAppearingInterpolator = new AccelerateDecelerateInterpolator();
+ private TimeInterpolator mDisappearingInterpolator = new AccelerateDecelerateInterpolator();
+ private TimeInterpolator mChangingAppearingInterpolator = new DecelerateInterpolator();
+ private TimeInterpolator mChangingDisappearingInterpolator = new DecelerateInterpolator();
/**
* This hashmap is used to store the animations that are currently running as part of
@@ -387,9 +386,9 @@
* {@link #APPEARING}, or {@link #DISAPPEARING}, which determines the animation whose
* duration is being set.
* @param interpolator The interpolator that the specified animation should use.
- * @see Animator#setInterpolator(android.view.animation.Interpolator)
+ * @see Animator#setInterpolator(TimeInterpolator)
*/
- public void setInterpolator(int transitionType, Interpolator interpolator) {
+ public void setInterpolator(int transitionType, TimeInterpolator interpolator) {
switch (transitionType) {
case CHANGE_APPEARING:
mChangingAppearingInterpolator = interpolator;
@@ -414,10 +413,10 @@
* @param transitionType one of {@link #CHANGE_APPEARING}, {@link #CHANGE_DISAPPEARING},
* {@link #APPEARING}, or {@link #DISAPPEARING}, which determines the animation whose
* duration is being set.
- * @return Interpolator The interpolator that the specified animation uses.
- * @see Animator#setInterpolator(android.view.animation.Interpolator)
+ * @return TimeInterpolator The interpolator that the specified animation uses.
+ * @see Animator#setInterpolator(TimeInterpolator)
*/
- public Interpolator getInterpolator(int transitionType) {
+ public TimeInterpolator getInterpolator(int transitionType) {
switch (transitionType) {
case CHANGE_APPEARING:
return mChangingAppearingInterpolator;
diff --git a/core/java/android/animation/TimeInterpolator.java b/core/java/android/animation/TimeInterpolator.java
new file mode 100644
index 0000000..8d795a8
--- /dev/null
+++ b/core/java/android/animation/TimeInterpolator.java
@@ -0,0 +1,38 @@
+/*
+ * 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.animation;
+
+/**
+ * A time interpolator defines the rate of change of an animation. This allows animations
+ * to have non-linear motion, such as acceleration and deceleration.
+ */
+public interface TimeInterpolator {
+
+ /**
+ * Maps a value representing the elapsed fraciton of an animation to a value that represents
+ * the interpolated fraction. This interpolated value is then multiplied by the change in
+ * value of an animation to derive the animated value at the current elapsed animation time.
+ *
+ * @param input A value between 0 and 1.0 indicating our current point
+ * in the animation where 0 represents the start and 1.0 represents
+ * the end
+ * @return The interpolation value. This value can be more than 1.0 for
+ * interpolators which overshoot their targets, or less than 0 for
+ * interpolators that undershoot their targets.
+ */
+ float getInterpolation(float input);
+}
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index f81b1ea..d2b17f0 100755
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -21,7 +21,6 @@
import android.os.Message;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
import java.util.ArrayList;
import java.util.HashMap;
@@ -36,7 +35,7 @@
* <p>By default, ValueAnimator uses non-linear time interpolation, via the
* {@link AccelerateDecelerateInterpolator} class, which accelerates into and decelerates
* out of an animation. This behavior can be changed by calling
- * {@link ValueAnimator#setInterpolator(Interpolator)}.</p>
+ * {@link ValueAnimator#setInterpolator(TimeInterpolator)}.</p>
*/
public class ValueAnimator<T> extends Animator {
@@ -95,7 +94,8 @@
private static final ArrayList<ValueAnimator> sPendingAnimations = new ArrayList<ValueAnimator>();
// The time interpolator to be used if none is set on the animation
- private static final Interpolator sDefaultInterpolator = new AccelerateDecelerateInterpolator();
+ private static final TimeInterpolator sDefaultInterpolator =
+ new AccelerateDecelerateInterpolator();
// type evaluators for the three primitive types handled by this implementation
private static final TypeEvaluator sIntEvaluator = new IntEvaluator();
@@ -178,7 +178,7 @@
* through this interpolator to calculate the interpolated fraction, which is then used to
* calculate the animated values.
*/
- private Interpolator mInterpolator = sDefaultInterpolator;
+ private TimeInterpolator mInterpolator = sDefaultInterpolator;
/**
* The set of listeners to be sent events through the life of an animation.
@@ -654,7 +654,7 @@
* @param value the interpolator to be used by this animation
*/
@Override
- public void setInterpolator(Interpolator value) {
+ public void setInterpolator(TimeInterpolator value) {
if (value != null) {
mInterpolator = value;
}
@@ -665,7 +665,7 @@
*
* @return The timing interpolator for this ValueAnimator.
*/
- public Interpolator getInterpolator() {
+ public TimeInterpolator getInterpolator() {
return mInterpolator;
}
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index ee49d97..7c87b79 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1745,35 +1745,11 @@
}
/**
- * @deprecated This functionality will be removed in the future; please do
- * not use.
- *
- * Control whether this activity is required to be persistent. By default
- * activities are not persistent; setting this to true will prevent the
- * system from stopping this activity or its process when running low on
- * resources.
- *
- * <p><em>You should avoid using this method</em>, it has severe negative
- * consequences on how well the system can manage its resources. A better
- * approach is to implement an application service that you control with
- * {@link Context#startService} and {@link Context#stopService}.
- *
- * @param isPersistent Control whether the current activity must be
- * persistent, true if so, false for the normal
- * behavior.
+ * @deprecated As of {@link android.os.Build.VERSION_CODES#GINGERBREAD}
+ * this is a no-op.
*/
@Deprecated
public void setPersistent(boolean isPersistent) {
- if (mParent == null) {
- try {
- ActivityManagerNative.getDefault()
- .setPersistent(mToken, isPersistent);
- } catch (RemoteException e) {
- // Empty
- }
- } else {
- throw new RuntimeException("setPersistent() not yet supported for embedded activities");
- }
}
/**
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index b34c243..8cc6428 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -345,17 +345,6 @@
return true;
}
- case SET_PERSISTENT_TRANSACTION: {
- data.enforceInterface(IActivityManager.descriptor);
- IBinder token = data.readStrongBinder();
- boolean isPersistent = data.readInt() != 0;
- if (token != null) {
- setPersistent(token, isPersistent);
- }
- reply.writeNoException();
- return true;
- }
-
case ATTACH_APPLICATION_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IApplicationThread app = ApplicationThreadNative.asInterface(
@@ -1640,18 +1629,6 @@
data.recycle();
reply.recycle();
}
- public void setPersistent(IBinder token, boolean isPersistent) throws RemoteException
- {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
- data.writeInterfaceToken(IActivityManager.descriptor);
- data.writeStrongBinder(token);
- data.writeInt(isPersistent ? 1 : 0);
- mRemote.transact(SET_PERSISTENT_TRANSACTION, data, reply, 0);
- reply.readException();
- data.recycle();
- reply.recycle();
- }
public void attachApplication(IApplicationThread app) throws RemoteException
{
Parcel data = Parcel.obtain();
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index cd229e3..c9d5448 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -116,7 +116,6 @@
public void unbroadcastIntent(IApplicationThread caller, Intent intent) throws RemoteException;
/* oneway */
public void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map, boolean abortBroadcast) throws RemoteException;
- public void setPersistent(IBinder token, boolean isPersistent) throws RemoteException;
public void attachApplication(IApplicationThread app) throws RemoteException;
/* oneway */
public void activityIdle(IBinder token, Configuration config) throws RemoteException;
@@ -455,7 +454,7 @@
int REPORT_THUMBNAIL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+27;
int GET_CONTENT_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+28;
int PUBLISH_CONTENT_PROVIDERS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+29;
- int SET_PERSISTENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+30;
+
int FINISH_SUB_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+31;
int GET_RUNNING_SERVICE_CONTROL_PANEL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+32;
int START_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+33;
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 3289120..da1aac4 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -1319,12 +1319,36 @@
}
/**
- * If a sync is active returns the information about it, otherwise returns false.
+ * If a sync is active returns the information about it, otherwise returns null.
+ * <p>
* @return the SyncInfo for the currently active sync or null if one is not active.
+ * @deprecated
+ * Since multiple concurrent syncs are now supported you should use
+ * {@link #getCurrentSyncs()} to get the accurate list of current syncs.
+ * This method returns the first item from the list of current syncs
+ * or null if there are none.
*/
+ @Deprecated
public static SyncInfo getCurrentSync() {
try {
- return getContentService().getCurrentSync();
+ final List<SyncInfo> syncs = getContentService().getCurrentSyncs();
+ if (syncs.isEmpty()) {
+ return null;
+ }
+ return syncs.get(0);
+ } catch (RemoteException e) {
+ throw new RuntimeException("the ContentService should always be reachable", e);
+ }
+ }
+
+ /**
+ * Returns a list with information about all the active syncs. This list will be empty
+ * if there are no active syncs.
+ * @return a List of SyncInfo objects for the currently active syncs.
+ */
+ public static List<SyncInfo> getCurrentSyncs() {
+ try {
+ return getContentService().getCurrentSyncs();
} catch (RemoteException e) {
throw new RuntimeException("the ContentService should always be reachable", e);
}
diff --git a/core/java/android/content/ContentService.java b/core/java/android/content/ContentService.java
index fc2dfc0..afe8483 100644
--- a/core/java/android/content/ContentService.java
+++ b/core/java/android/content/ContentService.java
@@ -386,19 +386,15 @@
return false;
}
- public SyncInfo getCurrentSync() {
+ public List<SyncInfo> getCurrentSyncs() {
mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
"no permission to read the sync stats");
long identityToken = clearCallingIdentity();
try {
- SyncManager syncManager = getSyncManager();
- if (syncManager != null) {
- return syncManager.getSyncStorageEngine().getCurrentSync();
- }
+ return getSyncManager().getSyncStorageEngine().getCurrentSyncs();
} finally {
restoreCallingIdentity(identityToken);
}
- return null;
}
public SyncStatusInfo getSyncStatus(Account account, String authority) {
diff --git a/core/java/android/content/IContentService.aidl b/core/java/android/content/IContentService.aidl
index a6368d5..86a9392 100644
--- a/core/java/android/content/IContentService.aidl
+++ b/core/java/android/content/IContentService.aidl
@@ -104,7 +104,7 @@
*/
boolean isSyncActive(in Account account, String authority);
- SyncInfo getCurrentSync();
+ List<SyncInfo> getCurrentSyncs();
/**
* Returns the types of the SyncAdapters that are registered with the system.
diff --git a/core/java/android/content/SyncInfo.java b/core/java/android/content/SyncInfo.java
index 616b05f..abfe964 100644
--- a/core/java/android/content/SyncInfo.java
+++ b/core/java/android/content/SyncInfo.java
@@ -18,12 +18,13 @@
import android.accounts.Account;
import android.os.Parcel;
+import android.os.Parcelable;
import android.os.Parcelable.Creator;
/**
* Information about the sync operation that is currently underway.
*/
-public class SyncInfo {
+public class SyncInfo implements Parcelable {
/** @hide */
public final int authorityId;
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index 487f6ce..17d85fa 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -1088,23 +1088,6 @@
}
/**
- * Return the currently active sync information, or null if there is no
- * active sync. Note that the returned object is the real, live active
- * sync object, so be careful what you do with it.
- * <p>
- * Since multiple concurrent syncs are now supported you should use
- * {@link #getCurrentSyncs()} to get the accurate list of current syncs.
- * This method returns the first item from the list of current syncs
- * or null if there are none.
- * @deprecated use {@link #getCurrentSyncs()}
- */
- public SyncInfo getCurrentSync() {
- synchronized (mAuthorities) {
- return !mCurrentSyncs.isEmpty() ? mCurrentSyncs.get(0) : null;
- }
- }
-
- /**
* Return a list of the currently active syncs. Note that the returned items are the
* real, live active sync objects, so be careful what you do with it.
*/
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index ba74d9b..643e747 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -399,7 +399,11 @@
pw.println(prefix + "uid=" + uid + " flags=0x" + Integer.toHexString(flags)
+ " theme=0x" + Integer.toHexString(theme));
pw.println(prefix + "sourceDir=" + sourceDir);
- if (!sourceDir.equals(publicSourceDir)) {
+ if (sourceDir == null) {
+ if (publicSourceDir != null) {
+ pw.println(prefix + "publicSourceDir=" + publicSourceDir);
+ }
+ } else if (!sourceDir.equals(publicSourceDir)) {
pw.println(prefix + "publicSourceDir=" + publicSourceDir);
}
if (resourceDirs != null) {
diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java
index 44b73c5..5fd2246 100644
--- a/core/java/android/os/BatteryManager.java
+++ b/core/java/android/os/BatteryManager.java
@@ -84,7 +84,15 @@
* String describing the technology of the current battery.
*/
public static final String EXTRA_TECHNOLOGY = "technology";
-
+
+ /**
+ * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+ * Boolean value set to true if an unsupported charger is attached
+ * to the device.
+ * {@hide}
+ */
+ public static final String EXTRA_INVALID_CHARGER = "invalid_charger";
+
// values for "status" field in the ACTION_BATTERY_CHANGED Intent
public static final int BATTERY_STATUS_UNKNOWN = 1;
public static final int BATTERY_STATUS_CHARGING = 2;
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index f0b00dd..2fadb82 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -135,10 +135,10 @@
@Override
void onPreDraw() {
- nPrepare(mRenderer);
+ nPrepare(mRenderer, mOpaque);
}
- private native void nPrepare(int renderer);
+ private native void nPrepare(int renderer, boolean opaque);
@Override
void onPostDraw() {
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 2cc4052..b87dbc5 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -585,7 +585,7 @@
@Override
GLES20Canvas createCanvas() {
- return mGlCanvas = new GLES20Canvas(true);
+ return mGlCanvas = new GLES20Canvas(mTranslucent);
}
@Override
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 155122f..79f1f5b 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -16,25 +16,41 @@
package android.view;
-import com.android.internal.view.BaseSurfaceHolder;
-import com.android.internal.view.IInputMethodCallback;
-import com.android.internal.view.IInputMethodSession;
-import com.android.internal.view.RootViewSurfaceTaker;
-
+import android.Manifest;
+import android.app.ActivityManagerNative;
+import android.content.ClipDescription;
+import android.content.ComponentCallbacks;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.CompatibilityInfo;
+import android.content.res.Configuration;
+import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
import android.graphics.Point;
import android.graphics.PointF;
+import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.Region;
-import android.os.*;
+import android.media.AudioManager;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Debug;
+import android.os.Handler;
+import android.os.LatencyTimer;
+import android.os.Looper;
+import android.os.Message;
+import android.os.ParcelFileDescriptor;
import android.os.Process;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.os.SystemProperties;
import android.util.AndroidRuntimeException;
import android.util.Config;
import android.util.DisplayMetrics;
-import android.util.Log;
import android.util.EventLog;
+import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
import android.view.View.MeasureSpec;
@@ -43,21 +59,14 @@
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.widget.Scroller;
-import android.content.pm.PackageManager;
-import android.content.res.CompatibilityInfo;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.content.ClipData;
-import android.content.ClipDescription;
-import android.content.ComponentCallbacks;
-import android.content.Context;
-import android.app.ActivityManagerNative;
-import android.Manifest;
-import android.media.AudioManager;
+import com.android.internal.view.BaseSurfaceHolder;
+import com.android.internal.view.IInputMethodCallback;
+import com.android.internal.view.IInputMethodSession;
+import com.android.internal.view.RootViewSurfaceTaker;
-import java.lang.ref.WeakReference;
import java.io.IOException;
import java.io.OutputStream;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
/**
diff --git a/core/java/android/view/WindowOrientationListener.java b/core/java/android/view/WindowOrientationListener.java
index 3e2e92b..2a76e33 100755
--- a/core/java/android/view/WindowOrientationListener.java
+++ b/core/java/android/view/WindowOrientationListener.java
@@ -109,7 +109,9 @@
}
public void setAllow180Rotation(boolean allowed) {
- mSensorEventListener.setAllow180Rotation(allowed);
+ if (mSensorEventListener != null) {
+ mSensorEventListener.setAllow180Rotation(allowed);
+ }
}
public int getCurrentRotation(int lastRotation) {
diff --git a/core/java/android/view/animation/Interpolator.java b/core/java/android/view/animation/Interpolator.java
index d14c3e33..5d0fe7e 100644
--- a/core/java/android/view/animation/Interpolator.java
+++ b/core/java/android/view/animation/Interpolator.java
@@ -16,24 +16,16 @@
package android.view.animation;
+import android.animation.TimeInterpolator;
+
/**
* An interpolator defines the rate of change of an animation. This allows
* the basic animation effects (alpha, scale, translate, rotate) to be
* accelerated, decelerated, repeated, etc.
*/
-public interface Interpolator {
-
- /**
- * Maps a point on the timeline to a multiplier to be applied to the
- * transformations of an animation.
- *
- * @param input A value between 0 and 1.0 indicating our current point
- * in the animation where 0 represents the start and 1.0 represents
- * the end
- * @return The interpolation value. This value can be more than 1.0 for
- * Interpolators which overshoot their targets, or less than 0 for
- * Interpolators that undershoot their targets.
- */
- float getInterpolation(float input);
-
+public interface Interpolator extends TimeInterpolator {
+ // A new interface, TimeInterpolator, was introduced for the new android.animation
+ // package. This older Interpolator interface extends TimeInterpolator so that users of
+ // the new Animator-based animations can use either the old Interpolator implementations or
+ // new classes that implement TimeInterpolator directly.
}
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 8bd3298..8e355d6 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -1401,6 +1401,16 @@
}
}
+ public void showInputMethodAndSubtypeEnabler(String topId) {
+ synchronized (mH) {
+ try {
+ mService.showInputMethodAndSubtypeEnablerFromClient(mClient, topId);
+ } catch (RemoteException e) {
+ Log.w(TAG, "IME died: " + mCurId, e);
+ }
+ }
+ }
+
void doDump(FileDescriptor fd, PrintWriter fout, String[] args) {
final Printer p = new PrintWriterPrinter(fout);
p.println("Input method client state for " + this + ":");
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index b00f88c..8c9f266 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -710,6 +710,9 @@
break;
case ADD_MESSAGE_TO_CONSOLE:
+ if (mWebChromeClient == null) {
+ break;
+ }
String message = msg.getData().getString("message");
String sourceID = msg.getData().getString("sourceID");
int lineNumber = msg.getData().getInt("lineNumber");
@@ -786,7 +789,9 @@
host, realm, username, password);
break;
case SET_INSTALLABLE_WEBAPP:
- mWebChromeClient.setInstallableWebApp();
+ if (mWebChromeClient != null) {
+ mWebChromeClient.setInstallableWebApp();
+ }
break;
}
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index d63af4e..1c954fc 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -4364,6 +4364,7 @@
switch (keyCode) {
case KeyEvent.KEYCODE_ENTER:
+ mEnterKeyIsDown = true;
// If ALT modifier is held, then we always insert a
// newline character.
if ((event.getMetaState()&KeyEvent.META_ALT_ON) == 0) {
@@ -4396,6 +4397,7 @@
break;
case KeyEvent.KEYCODE_DPAD_CENTER:
+ mDPadCenterIsDown = true;
if (shouldAdvanceFocusOnEnter()) {
return 0;
}
@@ -4490,6 +4492,7 @@
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_CENTER:
+ mDPadCenterIsDown = false;
/*
* If there is a click listener, just call through to
* super, which will invoke it.
@@ -4510,6 +4513,7 @@
return super.onKeyUp(keyCode, event);
case KeyEvent.KEYCODE_ENTER:
+ mEnterKeyIsDown = false;
if (mInputContentType != null
&& mInputContentType.onEditorActionListener != null
&& mInputContentType.enterDown) {
@@ -7288,9 +7292,21 @@
}
// Two ints packed in a long
+ return packRangeInLong(start, end);
+ }
+
+ private static long packRangeInLong(int start, int end) {
return (((long) start) << 32) | end;
}
+ private static int extractRangeStartFromLong(long range) {
+ return (int) (range >>> 32);
+ }
+
+ private static int extractRangeEndFromLong(long range) {
+ return (int) (range & 0x00000000FFFFFFFFL);
+ }
+
private void selectCurrentWord() {
// In case selection mode is started after an orientation change or after a select all,
// use the current selection instead of creating one
@@ -7298,67 +7314,31 @@
return;
}
- int selectionStart, selectionEnd;
+ int minOffset, maxOffset;
- // selectionModifierCursorController is not null at that point
- SelectionModifierCursorController selectionModifierCursorController =
- ((SelectionModifierCursorController) mSelectionModifierCursorController);
- int minOffset = selectionModifierCursorController.getMinTouchOffset();
- int maxOffset = selectionModifierCursorController.getMaxTouchOffset();
-
- if (minOffset == maxOffset) {
- int offset = Math.max(0, Math.min(minOffset, mTransformed.length()));
-
- // Tolerance, number of charaters around tapped position
- final int range = 1;
- final int max = mTransformed.length() - 1;
-
- // 'Smart' word selection: detect position between words
- for (int i = -range; i <= range; i++) {
- int index = offset + i;
- if (index >= 0 && index <= max) {
- if (Character.isSpaceChar(mTransformed.charAt(index))) {
- // Select current space
- selectionStart = index;
- selectionEnd = selectionStart + 1;
-
- // Extend selection to maximum space range
- while (selectionStart > 0 &&
- Character.isSpaceChar(mTransformed.charAt(selectionStart - 1))) {
- selectionStart--;
- }
- while (selectionEnd < max &&
- Character.isSpaceChar(mTransformed.charAt(selectionEnd))) {
- selectionEnd++;
- }
-
- Selection.setSelection((Spannable) mText, selectionStart, selectionEnd);
- return;
- }
- }
- }
-
- // 'Smart' word selection: detect position at beginning or end of text.
- if (offset <= range) {
- Selection.setSelection((Spannable) mText, 0, 0);
- return;
- }
- if (offset >= (max - range)) {
- Selection.setSelection((Spannable) mText, max + 1, max + 1);
- return;
- }
+ if (mDPadCenterIsDown || mEnterKeyIsDown) {
+ minOffset = getSelectionStart();
+ maxOffset = getSelectionEnd();
+ } else {
+ // selectionModifierCursorController is not null at that point
+ SelectionModifierCursorController selectionModifierCursorController =
+ ((SelectionModifierCursorController) mSelectionModifierCursorController);
+ minOffset = selectionModifierCursorController.getMinTouchOffset();
+ maxOffset = selectionModifierCursorController.getMaxTouchOffset();
}
+ int selectionStart, selectionEnd;
+
long wordLimits = getWordLimitsAt(minOffset);
if (wordLimits >= 0) {
- selectionStart = (int) (wordLimits >>> 32);
+ selectionStart = extractRangeStartFromLong(wordLimits);
} else {
selectionStart = Math.max(minOffset - 5, 0);
}
wordLimits = getWordLimitsAt(maxOffset);
if (wordLimits >= 0) {
- selectionEnd = (int) (wordLimits & 0x00000000FFFFFFFFL);
+ selectionEnd = extractRangeEndFromLong(wordLimits);
} else {
selectionEnd = Math.min(maxOffset + 5, mText.length());
}
@@ -7487,7 +7467,6 @@
switch (id) {
case ID_COPY_URL:
-
URLSpan[] urls = ((Spanned) mText).getSpans(min, max, URLSpan.class);
if (urls.length >= 1) {
ClipData clip = null;
@@ -7513,6 +7492,49 @@
return false;
}
+ /**
+ * Prepare text so that there are not zero or two spaces at beginning and end of region defined
+ * by [min, max] when replacing this region by paste.
+ */
+ private long prepareSpacesAroundPaste(int min, int max, CharSequence paste) {
+ // Paste adds/removes spaces before or after insertion as needed.
+ if (Character.isSpaceChar(paste.charAt(0))) {
+ if (min > 0 && Character.isSpaceChar(mTransformed.charAt(min - 1))) {
+ // Two spaces at beginning of paste: remove one
+ final int originalLength = mText.length();
+ ((Editable) mText).replace(min - 1, min, "");
+ // Due to filters, there is no garantee that exactly one character was
+ // removed. Count instead.
+ final int delta = mText.length() - originalLength;
+ min += delta;
+ max += delta;
+ }
+ } else {
+ if (min > 0 && !Character.isSpaceChar(mTransformed.charAt(min - 1))) {
+ // No space at beginning of paste: add one
+ final int originalLength = mText.length();
+ ((Editable) mText).replace(min, min, " ");
+ // Taking possible filters into account as above.
+ final int delta = mText.length() - originalLength;
+ min += delta;
+ max += delta;
+ }
+ }
+
+ if (Character.isSpaceChar(paste.charAt(paste.length() - 1))) {
+ if (max < mText.length() && Character.isSpaceChar(mTransformed.charAt(max))) {
+ // Two spaces at end of paste: remove one
+ ((Editable) mText).replace(max, max + 1, "");
+ }
+ } else {
+ if (max < mText.length() && !Character.isSpaceChar(mTransformed.charAt(max))) {
+ // No space at end of paste: add one
+ ((Editable) mText).replace(max, max, " ");
+ }
+ }
+ return packRangeInLong(min, max);
+ }
+
@Override
public boolean performLongClick() {
if (super.performLongClick()) {
@@ -7704,6 +7726,9 @@
CharSequence paste = clip.getItem(i).coerceToText(getContext());
if (paste != null) {
if (!didfirst) {
+ long minMax = prepareSpacesAroundPaste(min, max, paste);
+ min = extractRangeStartFromLong(minMax);
+ max = extractRangeEndFromLong(minMax);
Selection.setSelection((Spannable) mText, max);
((Editable) mText).replace(min, max, paste);
} else {
@@ -7714,7 +7739,6 @@
}
stopSelectionActionMode();
}
-
return true;
case ID_CUT:
@@ -8329,6 +8353,10 @@
private CursorController mSelectionModifierCursorController;
private ActionMode mSelectionActionMode;
private int mLastTouchOffset = -1;
+ // These are needed to desambiguate a long click. If the long click comes from ones of these, we
+ // select from the current cursor position. Otherwise, select from long pressed position.
+ private boolean mDPadCenterIsDown = false;
+ private boolean mEnterKeyIsDown = false;
// Created once and shared by different CursorController helper methods.
// Only one cursor controller is active at any time which prevent race conditions.
private static Rect sCursorControllerTempRect = new Rect();
diff --git a/core/java/com/android/internal/content/NativeLibraryHelper.java b/core/java/com/android/internal/content/NativeLibraryHelper.java
index 2a8cd94..00c4dbe 100644
--- a/core/java/com/android/internal/content/NativeLibraryHelper.java
+++ b/core/java/com/android/internal/content/NativeLibraryHelper.java
@@ -294,33 +294,44 @@
}
}
+ // Convenience method to call removeNativeBinariesFromDirLI(File)
+ public static boolean removeNativeBinariesLI(String nativeLibraryPath) {
+ return removeNativeBinariesFromDirLI(new File(nativeLibraryPath));
+ }
+
// Remove the native binaries of a given package. This simply
// gets rid of the files in the 'lib' sub-directory.
- public static void removeNativeBinariesLI(String nativeLibraryPath) {
+ public static boolean removeNativeBinariesFromDirLI(File nativeLibraryDir) {
if (DEBUG_NATIVE) {
- Slog.w(TAG, "Deleting native binaries from: " + nativeLibraryPath);
+ Slog.w(TAG, "Deleting native binaries from: " + nativeLibraryDir.getPath());
}
+ boolean deletedFiles = false;
+
/*
* Just remove any file in the directory. Since the directory is owned
* by the 'system' UID, the application is not supposed to have written
* anything there.
*/
- File binaryDir = new File(nativeLibraryPath);
- if (binaryDir.exists()) {
- File[] binaries = binaryDir.listFiles();
+ if (nativeLibraryDir.exists()) {
+ final File[] binaries = nativeLibraryDir.listFiles();
if (binaries != null) {
for (int nn = 0; nn < binaries.length; nn++) {
if (DEBUG_NATIVE) {
Slog.d(TAG, " Deleting " + binaries[nn].getName());
}
+
if (!binaries[nn].delete()) {
Slog.w(TAG, "Could not delete native binary: " + binaries[nn].getPath());
+ } else {
+ deletedFiles = true;
}
}
}
// Do not delete 'lib' directory itself, or this will prevent
// installation of future updates.
}
+
+ return deletedFiles;
}
}
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index d012b0f..bffec1d 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -49,6 +49,7 @@
void showInputMethodPickerFromClient(in IInputMethodClient client);
void showInputMethodSubtypePickerFromClient(in IInputMethodClient client);
+ void showInputMethodAndSubtypeEnablerFromClient(in IInputMethodClient client, String topId);
void setInputMethod(in IBinder token, String id);
void hideMySoftInput(in IBinder token, int flags);
void showMySoftInput(in IBinder token, int flags);
diff --git a/core/java/com/android/internal/view/InputMethodAndSubtypeEnabler.java b/core/java/com/android/internal/view/InputMethodAndSubtypeEnabler.java
new file mode 100644
index 0000000..200d49f
--- /dev/null
+++ b/core/java/com/android/internal/view/InputMethodAndSubtypeEnabler.java
@@ -0,0 +1,319 @@
+/*
+ * 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 com.android.internal.view;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceScreen;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodManager;
+import android.view.inputmethod.InputMethodSubtype;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+
+public class InputMethodAndSubtypeEnabler extends PreferenceActivity {
+
+ private boolean mHaveHardKeyboard;
+
+ private List<InputMethodInfo> mInputMethodProperties;
+
+ private final TextUtils.SimpleStringSplitter mStringColonSplitter
+ = new TextUtils.SimpleStringSplitter(':');
+
+ private String mLastInputMethodId;
+ private String mLastTickedInputMethodId;
+
+ private AlertDialog mDialog = null;
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ Configuration config = getResources().getConfiguration();
+ mHaveHardKeyboard = (config.keyboard == Configuration.KEYBOARD_QWERTY);
+ onCreateIMM();
+ setPreferenceScreen(createPreferenceHierarchy());
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ loadInputMethodSubtypeList();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ saveInputMethodSubtypeList();
+ }
+
+ @Override
+ public boolean onPreferenceTreeClick(
+ PreferenceScreen preferenceScreen, Preference preference) {
+
+ if (preference instanceof CheckBoxPreference) {
+ final CheckBoxPreference chkPref = (CheckBoxPreference) preference;
+ final String id = chkPref.getKey();
+ // TODO: Check subtype or not here
+ if (chkPref.isChecked()) {
+ InputMethodInfo selImi = null;
+ final int N = mInputMethodProperties.size();
+ for (int i = 0; i < N; i++) {
+ InputMethodInfo imi = mInputMethodProperties.get(i);
+ if (id.equals(imi.getId())) {
+ selImi = imi;
+ if (isSystemIme(imi)) {
+ setSubtypesPreferenceEnabled(id, true);
+ // This is a built-in IME, so no need to warn.
+ mLastTickedInputMethodId = id;
+ return super.onPreferenceTreeClick(preferenceScreen, preference);
+ }
+ break;
+ }
+ }
+ if (selImi == null) {
+ return super.onPreferenceTreeClick(preferenceScreen, preference);
+ }
+ chkPref.setChecked(false);
+ if (mDialog == null) {
+ mDialog = (new AlertDialog.Builder(this))
+ .setTitle(android.R.string.dialog_alert_title)
+ .setIcon(android.R.drawable.ic_dialog_alert)
+ .setCancelable(true)
+ .setPositiveButton(android.R.string.ok,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ chkPref.setChecked(true);
+ setSubtypesPreferenceEnabled(id, true);
+ mLastTickedInputMethodId = id;
+ }
+
+ })
+ .setNegativeButton(android.R.string.cancel,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ }
+
+ })
+ .create();
+ } else {
+ if (mDialog.isShowing()) {
+ mDialog.dismiss();
+ }
+ }
+ mDialog.setMessage(getResources().getString(
+ com.android.internal.R.string.ime_enabler_security_warning,
+ selImi.getServiceInfo().applicationInfo.loadLabel(getPackageManager())));
+ mDialog.show();
+ } else {
+ if (id.equals(mLastTickedInputMethodId)) {
+ mLastTickedInputMethodId = null;
+ }
+ setSubtypesPreferenceEnabled(id, false);
+ }
+ }
+ return super.onPreferenceTreeClick(preferenceScreen, preference);
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ if (mDialog != null) {
+ mDialog.dismiss();
+ mDialog = null;
+ }
+ }
+
+ private void onCreateIMM() {
+ InputMethodManager imm = (InputMethodManager) getSystemService(
+ Context.INPUT_METHOD_SERVICE);
+
+ // TODO: Change mInputMethodProperties to Map
+ mInputMethodProperties = imm.getInputMethodList();
+
+ mLastInputMethodId = Settings.Secure.getString(getContentResolver(),
+ Settings.Secure.DEFAULT_INPUT_METHOD);
+ }
+
+ private PreferenceScreen createPreferenceHierarchy() {
+ // Root
+ PreferenceScreen root = getPreferenceManager().createPreferenceScreen(this);
+
+ int N = (mInputMethodProperties == null ? 0 : mInputMethodProperties.size());
+ // TODO: Use iterator.
+ for (int i = 0; i < N; ++i) {
+ PreferenceCategory keyboardSettingsCategory = new PreferenceCategory(this);
+ root.addPreference(keyboardSettingsCategory);
+ InputMethodInfo property = mInputMethodProperties.get(i);
+ String prefKey = property.getId();
+
+ PackageManager pm = getPackageManager();
+ CharSequence label = property.loadLabel(pm);
+ boolean systemIME = isSystemIme(property);
+
+ keyboardSettingsCategory.setTitle(label);
+
+ // Add a check box.
+ // Don't show the toggle if it's the only keyboard in the system, or it's a system IME.
+ if (mHaveHardKeyboard || (N > 1 && !systemIME)) {
+ CheckBoxPreference chkbxPref = new CheckBoxPreference(this);
+ chkbxPref.setKey(prefKey);
+ chkbxPref.setTitle(label);
+ keyboardSettingsCategory.addPreference(chkbxPref);
+ }
+
+ ArrayList<InputMethodSubtype> subtypes = property.getSubtypes();
+ if (subtypes.size() > 0) {
+ PreferenceCategory subtypesCategory = new PreferenceCategory(this);
+ subtypesCategory.setTitle(getResources().getString(
+ com.android.internal.R.string.ime_enabler_subtype_title, label));
+ root.addPreference(subtypesCategory);
+ for (InputMethodSubtype subtype: subtypes) {
+ CharSequence subtypeLabel;
+ int nameResId = subtype.getNameResId();
+ if (nameResId != 0) {
+ subtypeLabel = pm.getText(property.getPackageName(), nameResId,
+ property.getServiceInfo().applicationInfo);
+ } else {
+ int modeResId = subtype.getModeResId();
+ CharSequence language = subtype.getLocale();
+ CharSequence mode = modeResId == 0 ? null
+ : pm.getText(property.getPackageName(), modeResId,
+ property.getServiceInfo().applicationInfo);
+ // TODO: Use more friendly Title and UI
+ subtypeLabel = (mode == null ? "" : mode) + ","
+ + (language == null ? "" : language);
+ }
+ CheckBoxPreference chkbxPref = new CheckBoxPreference(this);
+ chkbxPref.setKey(prefKey + subtype.hashCode());
+ chkbxPref.setTitle(subtypeLabel);
+ chkbxPref.setSummary(label);
+ subtypesCategory.addPreference(chkbxPref);
+ }
+ }
+ }
+ return root;
+ }
+
+ private void loadInputMethodSubtypeList() {
+ final HashSet<String> enabled = new HashSet<String>();
+ String enabledStr = Settings.Secure.getString(getContentResolver(),
+ Settings.Secure.ENABLED_INPUT_METHODS);
+ if (enabledStr != null) {
+ final TextUtils.SimpleStringSplitter splitter = mStringColonSplitter;
+ splitter.setString(enabledStr);
+ while (splitter.hasNext()) {
+ enabled.add(splitter.next());
+ }
+ }
+
+ // Update the statuses of the Check Boxes.
+ int N = mInputMethodProperties.size();
+ // TODO: Use iterator.
+ for (int i = 0; i < N; ++i) {
+ final String id = mInputMethodProperties.get(i).getId();
+ CheckBoxPreference pref = (CheckBoxPreference) findPreference(
+ mInputMethodProperties.get(i).getId());
+ if (pref != null) {
+ boolean isEnabled = enabled.contains(id);
+ pref.setChecked(isEnabled);
+ setSubtypesPreferenceEnabled(id, isEnabled);
+ }
+ }
+ mLastTickedInputMethodId = null;
+ }
+
+ private void saveInputMethodSubtypeList() {
+ StringBuilder builder = new StringBuilder();
+ StringBuilder disabledSysImes = new StringBuilder();
+
+ int firstEnabled = -1;
+ int N = mInputMethodProperties.size();
+ for (int i = 0; i < N; ++i) {
+ final InputMethodInfo property = mInputMethodProperties.get(i);
+ final String id = property.getId();
+ CheckBoxPreference pref = (CheckBoxPreference) findPreference(id);
+ boolean currentInputMethod = id.equals(mLastInputMethodId);
+ boolean systemIme = isSystemIme(property);
+ // TODO: Append subtypes by using the separator ";"
+ if (((N == 1 || systemIme) && !mHaveHardKeyboard)
+ || (pref != null && pref.isChecked())) {
+ if (builder.length() > 0) builder.append(':');
+ builder.append(id);
+ if (firstEnabled < 0) {
+ firstEnabled = i;
+ }
+ } else if (currentInputMethod) {
+ mLastInputMethodId = mLastTickedInputMethodId;
+ }
+ // If it's a disabled system ime, add it to the disabled list so that it
+ // doesn't get enabled automatically on any changes to the package list
+ if (pref != null && !pref.isChecked() && systemIme && mHaveHardKeyboard) {
+ if (disabledSysImes.length() > 0) disabledSysImes.append(":");
+ disabledSysImes.append(id);
+ }
+ }
+
+ // If the last input method is unset, set it as the first enabled one.
+ if (TextUtils.isEmpty(mLastInputMethodId)) {
+ if (firstEnabled >= 0) {
+ mLastInputMethodId = mInputMethodProperties.get(firstEnabled).getId();
+ } else {
+ mLastInputMethodId = null;
+ }
+ }
+
+ Settings.Secure.putString(getContentResolver(),
+ Settings.Secure.ENABLED_INPUT_METHODS, builder.toString());
+ Settings.Secure.putString(getContentResolver(),
+ Settings.Secure.DISABLED_SYSTEM_INPUT_METHODS, disabledSysImes.toString());
+ Settings.Secure.putString(getContentResolver(),
+ Settings.Secure.DEFAULT_INPUT_METHOD,
+ mLastInputMethodId != null ? mLastInputMethodId : "");
+ }
+
+ private void setSubtypesPreferenceEnabled(String id, boolean enabled) {
+ PreferenceScreen preferenceScreen = getPreferenceScreen();
+ final int N = mInputMethodProperties.size();
+ // TODO: Use iterator.
+ for (int i = 0; i < N; i++) {
+ InputMethodInfo imi = mInputMethodProperties.get(i);
+ if (id.equals(imi.getId())) {
+ for (InputMethodSubtype subtype: imi.getSubtypes()) {
+ preferenceScreen.findPreference(id + subtype.hashCode()).setEnabled(enabled);
+ }
+ }
+ }
+ }
+
+ private boolean isSystemIme(InputMethodInfo property) {
+ return (property.getServiceInfo().applicationInfo.flags
+ & ApplicationInfo.FLAG_SYSTEM) != 0;
+ }
+}
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 7521af4..2001919 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -103,8 +103,8 @@
}
static void android_view_GLES20Canvas_prepare(JNIEnv* env, jobject canvas,
- OpenGLRenderer* renderer) {
- renderer->prepare();
+ OpenGLRenderer* renderer, jboolean opaque) {
+ renderer->prepare(opaque);
}
static void android_view_GLES20Canvas_finish(JNIEnv* env, jobject canvas,
@@ -445,7 +445,7 @@
{ "nCreateRenderer", "()I", (void*) android_view_GLES20Canvas_createRenderer },
{ "nDestroyRenderer", "(I)V", (void*) android_view_GLES20Canvas_destroyRenderer },
{ "nSetViewport", "(III)V", (void*) android_view_GLES20Canvas_setViewport },
- { "nPrepare", "(I)V", (void*) android_view_GLES20Canvas_prepare },
+ { "nPrepare", "(IZ)V", (void*) android_view_GLES20Canvas_prepare },
{ "nFinish", "(I)V", (void*) android_view_GLES20Canvas_finish },
{ "nAcquireContext", "(I)V", (void*) android_view_GLES20Canvas_acquireContext },
{ "nReleaseContext", "(I)V", (void*) android_view_GLES20Canvas_releaseContext },
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 3a1d76f..f15d0a4 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1373,6 +1373,11 @@
android:permission="android.permission.BIND_WALLPAPER">
</service>
+ <activity android:name="com.android.internal.view.InputMethodAndSubtypeEnabler"
+ android:excludeFromRecents="true"
+ android:exported="true">
+ </activity>
+
<receiver android:name="com.android.server.BootReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 8b4f91f..521a739 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1639,7 +1639,7 @@
<!-- Do not translate. WebView User Agent string -->
<string name="web_user_agent" translatable="false">Mozilla/5.0 (Linux; U; <xliff:g id="x">Android %s</xliff:g>)
- AppleWebKit/534.9 (KHTML, like Gecko) Version/4.0 <xliff:g id="mobile">%s</xliff:g>Safari/534.9</string>
+ AppleWebKit/534.10 (KHTML, like Gecko) Version/4.0 <xliff:g id="mobile">%s</xliff:g>Safari/534.10</string>
<!-- Do not translate. WebView User Agent targeted content -->
<string name="web_user_agent_target_content" translatable="false">"Mobile "</string>
@@ -2385,5 +2385,9 @@
<item quantity="other"><xliff:g id="index" example="2">%d</xliff:g> of <xliff:g id="total" example="137">%d</xliff:g></item>
</plurals>
+ <!-- Warning message about security implications of enabling an input method, displayed as a dialog message when the user selects to enable an IME. -->
+ <string name="ime_enabler_security_warning">This input method may be able to collect all the text you type, including personal data like passwords and credit card numbers. It comes from the application <xliff:g id="ime_application_name">%1$s</xliff:g>. Use this input method?</string>
+ <!-- Label for selecting the input method to use -->
+ <string name="ime_enabler_subtype_title">Select inputmethods in <xliff:g id="ime_application_name">%1$s</xliff:g></string>
</resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 4b5047e..0f653f1 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1139,13 +1139,13 @@
<item name="android:textColorLink">?textColorLinkInverse</item>
</style>
- <style name="TextAppearance.Holo.Light.Large">
+ <style name="TextAppearance.Holo.Light.Large" parent="TextAppearance.Large">
</style>
- <style name="TextAppearance.Holo.Light.Medium">
+ <style name="TextAppearance.Holo.Light.Medium" parent="TextAppearance.Medium">
</style>
- <style name="TextAppearance.Holo.Light.Small">
+ <style name="TextAppearance.Holo.Light.Small" parent="TextAppearance.Small">
</style>
<style name="TextAppearance.Holo.Light.Large.Inverse">
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index 1289a9e..276e281 100755
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -579,7 +579,6 @@
private InstallParams installFromRawResource(String outFileName,
int rawResId, int flags, boolean cleanUp, boolean fail, int result,
int expInstallLocation) {
- PackageManager pm = mContext.getPackageManager();
InstallParams ip = new InstallParams(outFileName, rawResId);
installFromRawResource(ip, flags, cleanUp, fail, result, expInstallLocation);
return ip;
diff --git a/include/camera/CameraHardwareInterface.h b/include/camera/CameraHardwareInterface.h
index 3a77dd1..561a46d 100644
--- a/include/camera/CameraHardwareInterface.h
+++ b/include/camera/CameraHardwareInterface.h
@@ -21,6 +21,8 @@
#include <ui/egl/android_natives.h>
#include <utils/RefBase.h>
#include <surfaceflinger/ISurface.h>
+#include <ui/android_native_buffer.h>
+#include <ui/GraphicBuffer.h>
#include <camera/Camera.h>
#include <camera/CameraParameters.h>
@@ -47,6 +49,17 @@
const sp<IMemory>& dataPtr,
void* user);
+#ifdef USE_GRAPHIC_VIDEO_BUFFERS
+/**
+ * Replace data_callback_timestamp. Once we are done, this
+ * should be renamed as data_callback_timestamp, and the existing
+ * data_callback_timestamp should be deleted.
+ */
+typedef void (*videobuffer_callback_timestamp)(nsecs_t timestamp,
+ int32_t msgType,
+ const sp<android_native_buffer_t>& buf,
+ void* user);
+#endif
typedef void (*data_callback_timestamp)(nsecs_t timestamp,
int32_t msgType,
const sp<IMemory>& dataPtr,
@@ -87,6 +100,46 @@
public:
virtual ~CameraHardwareInterface() { }
+#ifdef USE_GRAPHIC_VIDEO_BUFFERS
+ /**
+ * Replace existing setCallbacks() method. Once we are done, the
+ * videobuffer_callback_timestamp parameter will be renamed to
+ * data_callback_timestamp, but its signature will be the same
+ * as videobuffer_callback_timestamp, which will be renamed
+ * to data_callback_timestamp and the exiting data_callback_timestamp
+ * will be deleted.
+ */
+ virtual void setCallbacks(notify_callback notify_cb,
+ data_callback data_cb,
+ videobuffer_callback_timestamp data_cb_timestamp,
+ void* user) = 0;
+
+ /**
+ * Replace releaseRecordingFrame(). releaseRecordingFrame() should be
+ * changed so that it has the same signature of releaseVideoBuffer(),
+ * once we are done, and releaseVideoBuffer() will be deleted.
+ */
+ virtual void releaseVideoBuffer(const sp<android_native_buffer_t>& buf) = 0;
+
+ /**
+ * This method should be called after startRecording().
+ *
+ * @param nBuffers the total number of video buffers allocated by the camera
+ * hal
+ * @param buffers an array allocated by the camera hal to hold the pointers
+ * to the individual video buffers. The video buffers and the buffers array
+ * should NOT be modified/released by camera hal until stopRecording() is
+ * called and all outstanding video buffers previously sent out via
+ * CAMERA_MSG_VIDEO_FRAME have been released via releaseVideoBuffer().
+ * Camera hal client must not release the individual buffers and the buffers
+ * array.
+ * @return no error if OK.
+ */
+ virtual status_t getVideoBufferInfo(
+ sp<android_native_buffer_t>** buffers,
+ size_t *nBuffers) = 0;
+#endif
+
/** Set the ANativeWindow to which preview frames are sent */
virtual status_t setPreviewWindow(const sp<ANativeWindow>& buf) = 0;
diff --git a/include/media/stagefright/AudioPlayer.h b/include/media/stagefright/AudioPlayer.h
index ed2f7d7..37af032 100644
--- a/include/media/stagefright/AudioPlayer.h
+++ b/include/media/stagefright/AudioPlayer.h
@@ -49,11 +49,9 @@
status_t start(bool sourceAlreadyStarted = false);
- void pause();
+ void pause(bool playPendingSamples = false);
void resume();
- void stop();
-
// Returns the timestamp of the last buffer played (in us).
int64_t getMediaTimeUs();
@@ -107,6 +105,8 @@
int64_t getRealTimeUsLocked() const;
+ void reset();
+
AudioPlayer(const AudioPlayer &);
AudioPlayer &operator=(const AudioPlayer &);
};
diff --git a/include/ui/InputDispatcher.h b/include/ui/InputDispatcher.h
index 8d4654f..246df8f8 100644
--- a/include/ui/InputDispatcher.h
+++ b/include/ui/InputDispatcher.h
@@ -212,8 +212,15 @@
int32_t ownerPid;
int32_t ownerUid;
- bool visibleFrameIntersects(const InputWindow* other) const;
bool touchableAreaContainsPoint(int32_t x, int32_t y) const;
+ bool frameContainsPoint(int32_t x, int32_t y) const;
+
+ /* Returns true if the window is of a trusted type that is allowed to silently
+ * overlay other windows for the purpose of implementing the secure views feature.
+ * Trusted overlays, such as IME windows, can partly obscure other windows without causing
+ * motion events to be delivered to them with AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED.
+ */
+ bool isTrustedOverlay() const;
};
@@ -973,7 +980,7 @@
bool shouldPokeUserActivityForCurrentInputTargetsLocked();
void pokeUserActivityLocked(nsecs_t eventTime, int32_t eventType);
bool checkInjectionPermission(const InputWindow* window, const InjectionState* injectionState);
- bool isWindowObscuredLocked(const InputWindow* window);
+ bool isWindowObscuredAtPointLocked(const InputWindow* window, int32_t x, int32_t y) const;
bool isWindowFinishedWithPreviousInputLocked(const InputWindow* window);
String8 getApplicationWindowLabelLocked(const InputApplication* application,
const InputWindow* window);
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index ce85d46..61e5408 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -342,7 +342,7 @@
mHeight = height;
}
-void DisplayListRenderer::prepare() {
+void DisplayListRenderer::prepare(bool opaque) {
mSnapshot = new Snapshot(mFirstSnapshot,
SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
mSaveCount = 1;
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 5d02bd7..0fbfce1 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -209,7 +209,7 @@
~DisplayListRenderer();
void setViewport(int width, int height);
- void prepare();
+ void prepare(bool opaque);
void acquireContext();
void releaseContext();
diff --git a/libs/hwui/OpenGLDebugRenderer.cpp b/libs/hwui/OpenGLDebugRenderer.cpp
index 4e5123e..b9583e5 100644
--- a/libs/hwui/OpenGLDebugRenderer.cpp
+++ b/libs/hwui/OpenGLDebugRenderer.cpp
@@ -23,10 +23,10 @@
namespace android {
namespace uirenderer {
-void OpenGLDebugRenderer::prepare() {
+void OpenGLDebugRenderer::prepare(bool opaque) {
mPrimitivesCount = 0;
LOGD("========= Frame start =========");
- OpenGLRenderer::prepare();
+ OpenGLRenderer::prepare(opaque);
}
void OpenGLDebugRenderer::finish() {
diff --git a/libs/hwui/OpenGLDebugRenderer.h b/libs/hwui/OpenGLDebugRenderer.h
index ce15512..2ac19ae 100644
--- a/libs/hwui/OpenGLDebugRenderer.h
+++ b/libs/hwui/OpenGLDebugRenderer.h
@@ -34,7 +34,7 @@
~OpenGLDebugRenderer() {
}
- void prepare();
+ void prepare(bool opaque);
void finish();
int saveLayer(float left, float top, float right, float bottom,
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index ee5fe22..5399668 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -150,7 +150,7 @@
mFirstSnapshot->viewport.set(0, 0, width, height);
}
-void OpenGLRenderer::prepare() {
+void OpenGLRenderer::prepare(bool opaque) {
mSnapshot = new Snapshot(mFirstSnapshot,
SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
mSaveCount = 1;
@@ -160,8 +160,10 @@
glDisable(GL_DITHER);
glDisable(GL_SCISSOR_TEST);
- glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
- glClear(GL_COLOR_BUFFER_BIT);
+ if (!opaque) {
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
glEnable(GL_SCISSOR_TEST);
glScissor(0, 0, mWidth, mHeight);
@@ -325,7 +327,10 @@
* - Issue the drawing
*
* Switching rendering target n + 1 times per drawn primitive is extremely costly.
- * To avoid this, layers are implemented in a different way here.
+ * To avoid this, layers are implemented in a different way here, at least in the
+ * general case. FBOs are used, as an optimization, when the "clip to layer" flag
+ * is set. When this flag is set we can redirect all drawing operations into a
+ * single FBO.
*
* This implementation relies on the frame buffer being at least RGBA 8888. When
* a layer is created, only a texture is created, not an FBO. The content of the
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index e3d4653..4caa8fb 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -67,7 +67,7 @@
virtual void setViewport(int width, int height);
- virtual void prepare();
+ virtual void prepare(bool opaque);
virtual void finish();
virtual void acquireContext();
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index d1a1b45..439e6fb 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -37,12 +37,8 @@
// Linear
"uniform mat4 screenSpace;\n",
// Circular
- "uniform vec2 gradientStart;\n"
- "uniform mat4 gradientMatrix;\n"
"uniform mat4 screenSpace;\n",
// Sweep
- "uniform vec2 gradientStart;\n"
- "uniform mat4 gradientMatrix;\n"
"uniform mat4 screenSpace;\n"
};
const char* gVS_Header_Uniforms_HasBitmap =
@@ -68,11 +64,9 @@
// Linear
" index = (screenSpace * position).x;\n",
// Circular
- " vec4 location = screenSpace * position;\n"
- " circular = (gradientMatrix * vec4(location.xy - gradientStart, 0.0, 0.0)).xy;\n",
+ " circular = (screenSpace * position).xy;\n",
// Sweep
- " vec4 location = screenSpace * position;\n"
- " sweep = (gradientMatrix * vec4(location.xy - gradientStart, 0.0, 0.0)).xy;\n"
+ " sweep = (screenSpace * position).xy;\n"
};
const char* gVS_Main_OutBitmapTexCoords =
" vec4 bitmapCoords = textureTransform * position;\n"
@@ -98,7 +92,6 @@
// Linear
"uniform sampler2D gradientSampler;\n",
// Circular
- "uniform float gradientRadius;\n"
"uniform sampler2D gradientSampler;\n",
// Sweep
"uniform sampler2D gradientSampler;\n"
@@ -130,7 +123,7 @@
// Linear
" vec4 gradientColor = texture2D(gradientSampler, vec2(index, 0.5));\n",
// Circular
- " float index = length(circular) * gradientRadius;\n"
+ " float index = length(circular);\n"
" vec4 gradientColor = texture2D(gradientSampler, vec2(index, 0.5));\n",
// Sweep
" float index = atan(sweep.y, sweep.x) * 0.15915494309; // inv(2 * PI)\n"
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index 83de2b2..fa85d20 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -49,7 +49,8 @@
SkiaShader::SkiaShader(Type type, SkShader* key, SkShader::TileMode tileX,
SkShader::TileMode tileY, SkMatrix* matrix, bool blend):
- mType(type), mKey(key), mTileX(tileX), mTileY(tileY), mMatrix(matrix), mBlend(blend) {
+ mType(type), mKey(key), mTileX(tileX), mTileY(tileY), mBlend(blend) {
+ setMatrix(matrix);
}
SkiaShader::~SkiaShader() {
@@ -69,6 +70,11 @@
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT);
}
+void SkiaShader::computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView) {
+ screenSpace.loadMultiply(mUnitMatrix, mShaderMatrix);
+ screenSpace.multiply(modelView);
+}
+
///////////////////////////////////////////////////////////////////////////////
// Bitmap shader
///////////////////////////////////////////////////////////////////////////////
@@ -76,6 +82,7 @@
SkiaBitmapShader::SkiaBitmapShader(SkBitmap* bitmap, SkShader* key, SkShader::TileMode tileX,
SkShader::TileMode tileY, SkMatrix* matrix, bool blend):
SkiaShader(kBitmap, key, tileX, tileY, matrix, blend), mBitmap(bitmap), mTexture(NULL) {
+ updateLocalMatrix(matrix);
}
void SkiaBitmapShader::describe(ProgramDescription& description, const Extensions& extensions) {
@@ -116,14 +123,7 @@
const float height = texture->height;
mat4 textureTransform;
- if (mMatrix) {
- SkMatrix inverse;
- mMatrix->invert(&inverse);
- textureTransform.load(inverse);
- textureTransform.multiply(modelView);
- } else {
- textureTransform.load(modelView);
- }
+ computeScreenSpaceMatrix(textureTransform, modelView);
// Uniforms
bindTexture(texture->id, mWrapS, mWrapT, textureSlot);
@@ -136,15 +136,7 @@
void SkiaBitmapShader::updateTransforms(Program* program, const mat4& modelView,
const Snapshot& snapshot) {
mat4 textureTransform;
- if (mMatrix) {
- SkMatrix inverse;
- mMatrix->invert(&inverse);
- textureTransform.load(inverse);
- textureTransform.multiply(modelView);
- } else {
- textureTransform.load(modelView);
- }
-
+ computeScreenSpaceMatrix(textureTransform, modelView);
glUniformMatrix4fv(program->getUniform("textureTransform"), 1,
GL_FALSE, &textureTransform.data[0]);
}
@@ -192,23 +184,6 @@
description.gradientType = ProgramDescription::kGradientLinear;
}
-void SkiaLinearGradientShader::computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView) {
- screenSpace.loadMultiply(mUnitMatrix, mShaderMatrix);
- screenSpace.multiply(modelView);
-}
-
-void SkiaLinearGradientShader::updateLocalMatrix(const SkMatrix* matrix) {
- if (matrix) {
- mat4 localMatrix(*matrix);
- mShaderMatrix.loadInverse(localMatrix);
- }
-}
-
-void SkiaLinearGradientShader::setMatrix(SkMatrix* matrix) {
- SkiaShader::setMatrix(matrix);
- updateLocalMatrix(matrix);
-}
-
void SkiaLinearGradientShader::setupProgram(Program* program, const mat4& modelView,
const Snapshot& snapshot, GLuint* textureUnit) {
GLuint textureSlot = (*textureUnit)++;
@@ -239,12 +214,23 @@
// Circular gradient shader
///////////////////////////////////////////////////////////////////////////////
+static void toCircularUnitMatrix(const float x, const float y, const float radius,
+ SkMatrix* matrix) {
+ const float inv = 1.0f / radius;
+ matrix->setTranslate(-x, -y);
+ matrix->postScale(inv, inv);
+}
+
SkiaCircularGradientShader::SkiaCircularGradientShader(float x, float y, float radius,
uint32_t* colors, float* positions, int count, SkShader* key, SkShader::TileMode tileMode,
SkMatrix* matrix, bool blend):
SkiaSweepGradientShader(kCircularGradient, x, y, colors, positions, count, key,
- tileMode, matrix, blend),
- mRadius(radius) {
+ tileMode, matrix, blend) {
+ SkMatrix unitMatrix;
+ toCircularUnitMatrix(x, y, radius, &unitMatrix);
+ mUnitMatrix.load(unitMatrix);
+
+ updateLocalMatrix(matrix);
}
void SkiaCircularGradientShader::describe(ProgramDescription& description,
@@ -253,28 +239,31 @@
description.gradientType = ProgramDescription::kGradientCircular;
}
-void SkiaCircularGradientShader::setupProgram(Program* program, const mat4& modelView,
- const Snapshot& snapshot, GLuint* textureUnit) {
- SkiaSweepGradientShader::setupProgram(program, modelView, snapshot, textureUnit);
- glUniform1f(program->getUniform("gradientRadius"), 1.0f / mRadius);
-}
-
///////////////////////////////////////////////////////////////////////////////
// Sweep gradient shader
///////////////////////////////////////////////////////////////////////////////
+static void toSweepUnitMatrix(const float x, const float y, SkMatrix* matrix) {
+ matrix->setTranslate(-x, -y);
+}
+
SkiaSweepGradientShader::SkiaSweepGradientShader(float x, float y, uint32_t* colors,
float* positions, int count, SkShader* key, SkMatrix* matrix, bool blend):
SkiaShader(kSweepGradient, key, SkShader::kClamp_TileMode,
SkShader::kClamp_TileMode, matrix, blend),
- mX(x), mY(y), mColors(colors), mPositions(positions), mCount(count) {
+ mColors(colors), mPositions(positions), mCount(count) {
+ SkMatrix unitMatrix;
+ toSweepUnitMatrix(x, y, &unitMatrix);
+ mUnitMatrix.load(unitMatrix);
+
+ updateLocalMatrix(matrix);
}
SkiaSweepGradientShader::SkiaSweepGradientShader(Type type, float x, float y, uint32_t* colors,
float* positions, int count, SkShader* key, SkShader::TileMode tileMode,
SkMatrix* matrix, bool blend):
SkiaShader(type, key, tileMode, tileMode, matrix, blend),
- mX(x), mY(y), mColors(colors), mPositions(positions), mCount(count) {
+ mColors(colors), mPositions(positions), mCount(count) {
}
SkiaSweepGradientShader::~SkiaSweepGradientShader() {
@@ -298,35 +287,19 @@
texture = mGradientCache->addLinearGradient(mKey, mColors, mPositions, mCount);
}
- float left = mX;
- float top = mY;
-
- mat4 shaderMatrix;
- if (mMatrix) {
- shaderMatrix.load(*mMatrix);
- shaderMatrix.mapPoint(left, top);
- }
-
- mat4 copy(shaderMatrix);
- shaderMatrix.loadInverse(copy);
-
- snapshot.transform->mapPoint(left, top);
-
- mat4 screenSpace(*snapshot.transform);
- screenSpace.multiply(modelView);
+ mat4 screenSpace;
+ computeScreenSpaceMatrix(screenSpace, modelView);
// Uniforms
bindTexture(texture->id, gTileModes[mTileX], gTileModes[mTileY], textureSlot);
glUniform1i(program->getUniform("gradientSampler"), textureSlot);
- glUniformMatrix4fv(program->getUniform("gradientMatrix"), 1, GL_FALSE, &shaderMatrix.data[0]);
- glUniform2f(program->getUniform("gradientStart"), left, top);
glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]);
}
void SkiaSweepGradientShader::updateTransforms(Program* program, const mat4& modelView,
const Snapshot& snapshot) {
- mat4 screenSpace(*snapshot.transform);
- screenSpace.multiply(modelView);
+ mat4 screenSpace;
+ computeScreenSpaceMatrix(screenSpace, modelView);
glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]);
}
diff --git a/libs/hwui/SkiaShader.h b/libs/hwui/SkiaShader.h
index 2c1eb35..2565e65 100644
--- a/libs/hwui/SkiaShader.h
+++ b/libs/hwui/SkiaShader.h
@@ -77,10 +77,21 @@
const Snapshot& snapshot) {
}
- virtual void setMatrix(SkMatrix* matrix) {
- mMatrix = matrix;
+ void setMatrix(SkMatrix* matrix) {
+ updateLocalMatrix(matrix);
}
+ void updateLocalMatrix(const SkMatrix* matrix) {
+ if (matrix) {
+ mat4 localMatrix(*matrix);
+ mShaderMatrix.loadInverse(localMatrix);
+ } else {
+ mShaderMatrix.loadIdentity();
+ }
+ }
+
+ void computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView);
+
protected:
inline void bindTexture(GLuint texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit);
@@ -88,11 +99,13 @@
SkShader* mKey;
SkShader::TileMode mTileX;
SkShader::TileMode mTileY;
- SkMatrix* mMatrix;
bool mBlend;
TextureCache* mTextureCache;
GradientCache* mGradientCache;
+
+ mat4 mUnitMatrix;
+ mat4 mShaderMatrix;
}; // struct SkiaShader
@@ -139,15 +152,7 @@
GLuint* textureUnit);
void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot);
- void setMatrix(SkMatrix* matrix);
-
private:
- void updateLocalMatrix(const SkMatrix* matrix);
- void computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView);
-
- mat4 mUnitMatrix;
- mat4 mShaderMatrix;
-
float* mBounds;
uint32_t* mColors;
float* mPositions;
@@ -163,7 +168,7 @@
~SkiaSweepGradientShader();
virtual void describe(ProgramDescription& description, const Extensions& extensions);
- virtual void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
+ void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
GLuint* textureUnit);
void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot);
@@ -171,7 +176,6 @@
SkiaSweepGradientShader(Type type, float x, float y, uint32_t* colors, float* positions,
int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
- float mX, mY;
uint32_t* mColors;
float* mPositions;
int mCount;
@@ -185,11 +189,6 @@
int count, SkShader* key,SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
void describe(ProgramDescription& description, const Extensions& extensions);
- void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
- GLuint* textureUnit);
-
-private:
- float mRadius;
}; // struct SkiaCircularGradientShader
/**
diff --git a/libs/rs/java/tests/src/com/android/rs/test/primitives.rs b/libs/rs/java/tests/src/com/android/rs/test/primitives.rs
index 5312bcc..012af9c 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/primitives.rs
+++ b/libs/rs/java/tests/src/com/android/rs/test/primitives.rs
@@ -2,15 +2,21 @@
#pragma rs export_func(primitives_test)
+#pragma rs export_var(floatTest, doubleTest, charTest, shortTest, intTest, longTest, longlongTest)
+
// Testing primitive types
static float floatTest = 1.99f;
static double doubleTest = 2.05;
static char charTest = -8;
static short shortTest = -16;
static int intTest = -32;
+static long longTest = 17179869184l; // 1 << 34
+static long long longlongTest = 68719476736l; // 1 << 36
+
static uchar ucharTest = 8;
static ushort ushortTest = 16;
static uint uintTest = 32;
+static int64_t int64_tTest = -17179869184l; // - 1 << 34
static bool test_primitive_types(uint32_t index) {
bool failed = false;
@@ -21,9 +27,13 @@
_RS_ASSERT(charTest == -8);
_RS_ASSERT(shortTest == -16);
_RS_ASSERT(intTest == -32);
+ _RS_ASSERT(longTest == 17179869184l);
+ _RS_ASSERT(longlongTest == 68719476736l);
+
_RS_ASSERT(ucharTest == 8);
_RS_ASSERT(ushortTest == 16);
_RS_ASSERT(uintTest == 32);
+ _RS_ASSERT(int64_tTest == -17179869184l);
float time = end(index);
diff --git a/libs/rs/scriptc/rs_core.rsh b/libs/rs/scriptc/rs_core.rsh
index 99fc166..9950184 100644
--- a/libs/rs/scriptc/rs_core.rsh
+++ b/libs/rs/scriptc/rs_core.rsh
@@ -1,6 +1,30 @@
#ifndef __RS_CORE_RSH__
#define __RS_CORE_RSH__
+// Debugging, print to the LOG a description string and a value.
+extern void __attribute__((overloadable))
+ rsDebug(const char *, float);
+extern void __attribute__((overloadable))
+ rsDebug(const char *, float, float);
+extern void __attribute__((overloadable))
+ rsDebug(const char *, float, float, float);
+extern void __attribute__((overloadable))
+ rsDebug(const char *, float, float, float, float);
+extern void __attribute__((overloadable))
+ rsDebug(const char *, const rs_matrix4x4 *);
+extern void __attribute__((overloadable))
+ rsDebug(const char *, const rs_matrix3x3 *);
+extern void __attribute__((overloadable))
+ rsDebug(const char *, const rs_matrix2x2 *);
+extern void __attribute__((overloadable))
+ rsDebug(const char *, int);
+extern void __attribute__((overloadable))
+ rsDebug(const char *, uint);
+extern void __attribute__((overloadable))
+ rsDebug(const char *, const void *);
+#define RS_DEBUG(a) rsDebug(#a, a)
+#define RS_DEBUG_MARKER rsDebug(__FILE__, __LINE__)
+
static void __attribute__((overloadable)) rsDebug(const char *s, float2 v) {
rsDebug(s, v.x, v.y);
}
diff --git a/libs/rs/scriptc/rs_math.rsh b/libs/rs/scriptc/rs_math.rsh
index 5720b05..d059997 100644
--- a/libs/rs/scriptc/rs_math.rsh
+++ b/libs/rs/scriptc/rs_math.rsh
@@ -1,34 +1,6 @@
#ifndef __RS_MATH_RSH__
#define __RS_MATH_RSH__
-// Debugging, print to the LOG a description string and a value.
-extern void __attribute__((overloadable))
- rsDebug(const char *, float);
-extern void __attribute__((overloadable))
- rsDebug(const char *, float, float);
-extern void __attribute__((overloadable))
- rsDebug(const char *, float, float, float);
-extern void __attribute__((overloadable))
- rsDebug(const char *, float, float, float, float);
-extern void __attribute__((overloadable))
- rsDebug(const char *, const rs_matrix4x4 *);
-extern void __attribute__((overloadable))
- rsDebug(const char *, const rs_matrix3x3 *);
-extern void __attribute__((overloadable))
- rsDebug(const char *, const rs_matrix2x2 *);
-extern void __attribute__((overloadable))
- rsDebug(const char *, int);
-extern void __attribute__((overloadable))
- rsDebug(const char *, uint);
-extern void __attribute__((overloadable))
- rsDebug(const char *, const void *);
-#define RS_DEBUG(a) rsDebug(#a, a)
-#define RS_DEBUG_MARKER rsDebug(__FILE__, __LINE__)
-
-
-#include "rs_cl.rsh"
-#include "rs_core.rsh"
-
extern void __attribute__((overloadable))
rsSetObject(rs_element *dst, rs_element src);
extern void __attribute__((overloadable))
diff --git a/libs/rs/scriptc/rs_types.rsh b/libs/rs/scriptc/rs_types.rsh
index dd42972..212eb83 100644
--- a/libs/rs/scriptc/rs_types.rsh
+++ b/libs/rs/scriptc/rs_types.rsh
@@ -1,3 +1,5 @@
+#ifndef __RS_TYPES_RSH__
+#define __RS_TYPES_RSH__
typedef char int8_t;
typedef short int16_t;
@@ -72,3 +74,4 @@
#define RS_PACKED __attribute__((packed, aligned(4)))
+#endif
diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp
index a6f5a1b..75b2294 100644
--- a/libs/ui/InputDispatcher.cpp
+++ b/libs/ui/InputDispatcher.cpp
@@ -134,18 +134,21 @@
// --- InputWindow ---
-bool InputWindow::visibleFrameIntersects(const InputWindow* other) const {
- return visibleFrameRight > other->visibleFrameLeft
- && visibleFrameLeft < other->visibleFrameRight
- && visibleFrameBottom > other->visibleFrameTop
- && visibleFrameTop < other->visibleFrameBottom;
-}
-
bool InputWindow::touchableAreaContainsPoint(int32_t x, int32_t y) const {
return x >= touchableAreaLeft && x <= touchableAreaRight
&& y >= touchableAreaTop && y <= touchableAreaBottom;
}
+bool InputWindow::frameContainsPoint(int32_t x, int32_t y) const {
+ return x >= frameLeft && x <= frameRight
+ && y >= frameTop && y <= frameBottom;
+}
+
+bool InputWindow::isTrustedOverlay() const {
+ return layoutParamsType == TYPE_INPUT_METHOD
+ || layoutParamsType == TYPE_INPUT_METHOD_DIALOG;
+}
+
// --- InputDispatcher ---
@@ -1053,8 +1056,12 @@
if (maskedAction == AMOTION_EVENT_ACTION_DOWN
&& (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
- mTempTouchState.addOrUpdateWindow(window,
- InputTarget::FLAG_OUTSIDE, BitSet32(0));
+ int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;
+ if (isWindowObscuredAtPointLocked(window, x, y)) {
+ outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
+ }
+
+ mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));
}
}
}
@@ -1083,10 +1090,6 @@
// (May be NULL which is why we put this code block before the next check.)
newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
}
- int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
- if (isSplit) {
- targetFlags |= InputTarget::FLAG_SPLIT;
- }
// If we did not find a touched window then fail.
if (! newTouchedWindow) {
@@ -1106,6 +1109,15 @@
goto Failed;
}
+ // Set target flags.
+ int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
+ if (isSplit) {
+ targetFlags |= InputTarget::FLAG_SPLIT;
+ }
+ if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {
+ targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
+ }
+
// Update the temporary touch state.
BitSet32 pointerIds;
if (isSplit) {
@@ -1186,23 +1198,13 @@
for (size_t i = 0; i < mWindows.size(); i++) {
const InputWindow* window = & mWindows[i];
if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
- mTempTouchState.addOrUpdateWindow(window, 0, BitSet32(0));
+ mTempTouchState.addOrUpdateWindow(window,
+ InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));
}
}
}
}
- // If a touched window has been obscured at any point during the touch gesture, set
- // the appropriate flag so we remember it for the entire gesture.
- for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
- TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
- if ((touchedWindow.targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) == 0) {
- if (isWindowObscuredLocked(touchedWindow.window)) {
- touchedWindow.targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
- }
- }
- }
-
// Success! Output targets.
injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
@@ -1326,14 +1328,15 @@
return true;
}
-bool InputDispatcher::isWindowObscuredLocked(const InputWindow* window) {
+bool InputDispatcher::isWindowObscuredAtPointLocked(
+ const InputWindow* window, int32_t x, int32_t y) const {
size_t numWindows = mWindows.size();
for (size_t i = 0; i < numWindows; i++) {
const InputWindow* other = & mWindows.itemAt(i);
if (other == window) {
break;
}
- if (other->visible && window->visibleFrameIntersects(other)) {
+ if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
return true;
}
}
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index bc5f9fa..e5fa0f8 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -117,6 +117,10 @@
Files.FileColumns.DATE_MODIFIED, // 3
};
+ private static final String[] ID_PROJECTION = new String[] {
+ Files.FileColumns._ID,
+ };
+
private static final int FILES_PRESCAN_ID_COLUMN_INDEX = 0;
private static final int FILES_PRESCAN_PATH_COLUMN_INDEX = 1;
private static final int FILES_PRESCAN_FORMAT_COLUMN_INDEX = 2;
@@ -933,6 +937,14 @@
c.close();
}
}
+
+ // compute original size of images
+ mOriginalCount = 0;
+ c = mMediaProvider.query(mImagesUri, ID_PROJECTION, null, null, null);
+ if (c != null) {
+ mOriginalCount = c.getCount();
+ c.close();
+ }
}
private boolean inScanDirectory(String path, String[] directories) {
diff --git a/media/java/android/media/videoeditor/AudioTrack.java b/media/java/android/media/videoeditor/AudioTrack.java
index 3ebad00..076cc31 100755
--- a/media/java/android/media/videoeditor/AudioTrack.java
+++ b/media/java/android/media/videoeditor/AudioTrack.java
@@ -18,17 +18,12 @@
import java.io.IOException;
-import android.util.Log;
-
/**
* This class allows to handle an audio track. This audio file is mixed with the
* audio samples of the MediaItems.
* {@hide}
*/
public class AudioTrack {
- // Logging
- private static final String TAG = "AudioTrack";
-
// Instance variables
private final String mUniqueId;
private final String mFilename;
@@ -53,129 +48,6 @@
// The audio waveform filename
private String mAudioWaveformFilename;
- private PlaybackThread mPlaybackThread;
-
- /**
- * This listener interface is used by the AudioTrack to emit playback
- * progress notifications.
- */
- public interface PlaybackProgressListener {
- /**
- * This method notifies the listener of the current time position while
- * playing an audio track
- *
- * @param audioTrack The audio track
- * @param timeMs The current playback position (expressed in milliseconds
- * since the beginning of the audio track).
- * @param end true if the end of the audio track was reached
- */
- public void onProgress(AudioTrack audioTrack, long timeMs, boolean end);
- }
-
- /**
- * The playback thread
- */
- private class PlaybackThread extends Thread {
- // Instance variables
- private final PlaybackProgressListener mListener;
- private final long mFromMs, mToMs;
- private boolean mRun;
- private final boolean mLoop;
- private long mPositionMs;
-
- /**
- * Constructor
- *
- * @param fromMs The time (relative to the beginning of the audio track)
- * at which the playback will start
- * @param toMs The time (relative to the beginning of the audio track) at
- * which the playback will stop. Use -1 to play to the end of
- * the audio track
- * @param loop true if the playback should be looped once it reaches the
- * end
- * @param listener The listener which will be notified of the playback
- * progress
- */
- public PlaybackThread(long fromMs, long toMs, boolean loop,
- PlaybackProgressListener listener) {
- mPositionMs = mFromMs = fromMs;
- if (toMs < 0) {
- mToMs = mDurationMs;
- } else {
- mToMs = toMs;
- }
- mLoop = loop;
- mListener = listener;
- mRun = true;
- }
-
- /*
- * {@inheritDoc}
- */
- @Override
- public void run() {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "===> PlaybackThread.run enter");
- }
-
- while (mRun) {
- try {
- sleep(100);
- } catch (InterruptedException ex) {
- break;
- }
-
- mPositionMs += 100;
-
- if (mPositionMs >= mToMs) {
- if (!mLoop) {
- if (mListener != null) {
- mListener.onProgress(AudioTrack.this, mPositionMs, true);
- }
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "PlaybackThread.run playback complete");
- }
- break;
- } else {
- // Fire a notification for the end of the clip
- if (mListener != null) {
- mListener.onProgress(AudioTrack.this, mToMs, false);
- }
-
- // Rewind
- mPositionMs = mFromMs;
- if (mListener != null) {
- mListener.onProgress(AudioTrack.this, mPositionMs, false);
- }
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "PlaybackThread.run playback complete");
- }
- }
- } else {
- if (mListener != null) {
- mListener.onProgress(AudioTrack.this, mPositionMs, false);
- }
- }
- }
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "===> PlaybackThread.run exit");
- }
- }
-
- /**
- * Stop the playback
- *
- * @return The stop position
- */
- public long stopPlayback() {
- mRun = false;
- try {
- join();
- } catch (InterruptedException ex) {
- }
- return mPositionMs;
- }
- };
/**
* An object of this type cannot be instantiated by using the default
@@ -509,50 +381,6 @@
}
/**
- * Start the playback of this audio track. This method does not block (does
- * not wait for the playback to complete).
- *
- * @param fromMs The time (relative to the beginning of the audio track) at
- * which the playback will start
- * @param toMs The time (relative to the beginning of the audio track) at
- * which the playback will stop. Use -1 to play to the end of the
- * audio track
- * @param loop true if the playback should be looped once it reaches the end
- * @param listener The listener which will be notified of the playback
- * progress
- * @throws IllegalArgumentException if fromMs or toMs is beyond the playback
- * duration
- * @throws IllegalStateException if a playback, preview or an export is
- * already in progress
- */
- public void startPlayback(long fromMs, long toMs, boolean loop,
- PlaybackProgressListener listener) {
- if (fromMs >= mDurationMs) {
- return;
- }
- mPlaybackThread = new PlaybackThread(fromMs, toMs, loop, listener);
- mPlaybackThread.start();
- }
-
- /**
- * Stop the audio track playback. This method blocks until the ongoing
- * playback is stopped.
- *
- * @return The accurate current time when stop is effective expressed in
- * milliseconds
- */
- public long stopPlayback() {
- final long stopTimeMs;
- if (mPlaybackThread != null) {
- stopTimeMs = mPlaybackThread.stopPlayback();
- mPlaybackThread = null;
- } else {
- stopTimeMs = 0;
- }
- return stopTimeMs;
- }
-
- /**
* This API allows to generate a file containing the sample volume levels of
* this audio track object. This function may take significant time and is
* blocking. The filename can be retrieved using getAudioWaveformFilename().
diff --git a/media/java/android/media/videoeditor/MediaVideoItem.java b/media/java/android/media/videoeditor/MediaVideoItem.java
index dd12336..f71f4f4 100755
--- a/media/java/android/media/videoeditor/MediaVideoItem.java
+++ b/media/java/android/media/videoeditor/MediaVideoItem.java
@@ -19,7 +19,6 @@
import java.io.IOException;
import android.graphics.Bitmap;
-import android.util.Log;
import android.view.SurfaceHolder;
/**
@@ -27,9 +26,6 @@
* {@hide}
*/
public class MediaVideoItem extends MediaItem {
- // Logging
- private static final String TAG = "MediaVideoItem";
-
// Instance variables
private final int mWidth;
private final int mHeight;
@@ -50,142 +46,6 @@
private int mVolumePercentage;
private boolean mMuted;
private String mAudioWaveformFilename;
- private PlaybackThread mPlaybackThread;
-
- /**
- * This listener interface is used by the MediaVideoItem to emit playback
- * progress notifications. This callback should be invoked after the
- * number of frames specified by
- * {@link #startPlayback(SurfaceHolder surfaceHolder, long fromMs,
- * int callbackAfterFrameCount, PlaybackProgressListener listener)}
- */
- public interface PlaybackProgressListener {
- /**
- * This method notifies the listener of the current time position while
- * playing a media item
- *
- * @param mediaItem The media item
- * @param timeMs The current playback position (expressed in milliseconds
- * since the beginning of the media item).
- * @param end true if the end of the media item was reached
- */
- public void onProgress(MediaVideoItem mediaItem, long timeMs, boolean end);
- }
-
- /**
- * The playback thread
- */
- private class PlaybackThread extends Thread {
- // Instance variables
- private final static long FRAME_DURATION = 33;
- private final PlaybackProgressListener mListener;
- private final int mCallbackAfterFrameCount;
- private final long mFromMs, mToMs;
- private boolean mRun;
- private final boolean mLoop;
- private long mPositionMs;
-
- /**
- * Constructor
- *
- * @param fromMs The time (relative to the beginning of the media item)
- * at which the playback will start
- * @param toMs The time (relative to the beginning of the media item) at
- * which the playback will stop. Use -1 to play to the end of
- * the media item
- * @param loop true if the playback should be looped once it reaches the
- * end
- * @param callbackAfterFrameCount The listener interface should be
- * invoked after the number of frames specified by this
- * parameter.
- * @param listener The listener which will be notified of the playback
- * progress
- */
- public PlaybackThread(long fromMs, long toMs, boolean loop, int callbackAfterFrameCount,
- PlaybackProgressListener listener) {
- mPositionMs = mFromMs = fromMs;
- if (toMs < 0) {
- mToMs = mDurationMs;
- } else {
- mToMs = toMs;
- }
- mLoop = loop;
- mCallbackAfterFrameCount = callbackAfterFrameCount;
- mListener = listener;
- mRun = true;
- }
-
- /*
- * {@inheritDoc}
- */
- @Override
- public void run() {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "===> PlaybackThread.run enter");
- }
- int frameCount = 0;
- while (mRun) {
- try {
- sleep(FRAME_DURATION);
- } catch (InterruptedException ex) {
- break;
- }
- frameCount++;
- mPositionMs += FRAME_DURATION;
-
- if (mPositionMs >= mToMs) {
- if (!mLoop) {
- if (mListener != null) {
- mListener.onProgress(MediaVideoItem.this, mPositionMs, true);
- }
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "PlaybackThread.run playback complete");
- }
- break;
- } else {
- // Fire a notification for the end of the clip
- if (mListener != null) {
- mListener.onProgress(MediaVideoItem.this, mToMs, false);
- }
-
- // Rewind
- mPositionMs = mFromMs;
- if (mListener != null) {
- mListener.onProgress(MediaVideoItem.this, mPositionMs, false);
- }
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "PlaybackThread.run playback complete");
- }
- frameCount = 0;
- }
- } else {
- if (frameCount == mCallbackAfterFrameCount) {
- if (mListener != null) {
- mListener.onProgress(MediaVideoItem.this, mPositionMs, false);
- }
- frameCount = 0;
- }
- }
- }
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "===> PlaybackThread.run exit");
- }
- }
-
- /**
- * Stop the playback
- *
- * @return The stop position
- */
- public long stopPlayback() {
- mRun = false;
- try {
- join();
- } catch (InterruptedException ex) {
- }
- return mPositionMs;
- }
- };
/**
* An object of this type cannot be instantiated with a default constructor
@@ -408,57 +268,6 @@
}
/**
- * Start the playback of this media item. This method does not block (does
- * not wait for the playback to complete). The PlaybackProgressListener
- * allows to track the progress at the time interval determined by the
- * callbackAfterFrameCount parameter. The SurfaceHolder has to be created
- * and ready for use before calling this method.
- *
- * @param surfaceHolder SurfaceHolder where the frames are rendered.
- * @param fromMs The time (relative to the beginning of the media item) at
- * which the playback will start
- * @param toMs The time (relative to the beginning of the media item) at
- * which the playback will stop. Use -1 to play to the end of the
- * media item
- * @param loop true if the playback should be looped once it reaches the end
- * @param callbackAfterFrameCount The listener interface should be invoked
- * after the number of frames specified by this parameter.
- * @param listener The listener which will be notified of the playback
- * progress
- * @throws IllegalArgumentException if fromMs or toMs is beyond the playback
- * duration
- * @throws IllegalStateException if a playback, preview or an export is
- * already in progress
- */
- public void startPlayback(SurfaceHolder surfaceHolder, long fromMs, long toMs, boolean loop,
- int callbackAfterFrameCount, PlaybackProgressListener listener) {
- if (fromMs >= mDurationMs) {
- return;
- }
- mPlaybackThread = new PlaybackThread(fromMs, toMs, loop, callbackAfterFrameCount,
- listener);
- mPlaybackThread.start();
- }
-
- /**
- * Stop the media item playback. This method blocks until the ongoing
- * playback is stopped.
- *
- * @return The accurate current time when stop is effective expressed in
- * milliseconds
- */
- public long stopPlayback() {
- final long stopTimeMs;
- if (mPlaybackThread != null) {
- stopTimeMs = mPlaybackThread.stopPlayback();
- mPlaybackThread = null;
- } else {
- stopTimeMs = 0;
- }
- return stopTimeMs;
- }
-
- /**
* This API allows to generate a file containing the sample volume levels of
* the Audio track of this media item. This function may take significant
* time and is blocking. The file can be retrieved using
diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp
index b314114..5ff934d 100644
--- a/media/libstagefright/AudioPlayer.cpp
+++ b/media/libstagefright/AudioPlayer.cpp
@@ -55,7 +55,7 @@
AudioPlayer::~AudioPlayer() {
if (mStarted) {
- stop();
+ reset();
}
}
@@ -165,13 +165,21 @@
return OK;
}
-void AudioPlayer::pause() {
+void AudioPlayer::pause(bool playPendingSamples) {
CHECK(mStarted);
- if (mAudioSink.get() != NULL) {
- mAudioSink->pause();
+ if (playPendingSamples) {
+ if (mAudioSink.get() != NULL) {
+ mAudioSink->stop();
+ } else {
+ mAudioTrack->stop();
+ }
} else {
- mAudioTrack->stop();
+ if (mAudioSink.get() != NULL) {
+ mAudioSink->pause();
+ } else {
+ mAudioTrack->pause();
+ }
}
}
@@ -185,7 +193,7 @@
}
}
-void AudioPlayer::stop() {
+void AudioPlayer::reset() {
CHECK(mStarted);
if (mAudioSink.get() != NULL) {
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 31c03ad..4f5ff75 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -579,7 +579,7 @@
notifyListener_l(
MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, mStreamDoneStatus);
- pause_l();
+ pause_l(true /* at eos */);
mFlags |= AT_EOS;
return;
@@ -603,7 +603,7 @@
LOGV("MEDIA_PLAYBACK_COMPLETE");
notifyListener_l(MEDIA_PLAYBACK_COMPLETE);
- pause_l();
+ pause_l(true /* at eos */);
mFlags |= AT_EOS;
}
@@ -752,7 +752,7 @@
return pause_l();
}
-status_t AwesomePlayer::pause_l() {
+status_t AwesomePlayer::pause_l(bool at_eos) {
if (!(mFlags & PLAYING)) {
return OK;
}
@@ -760,7 +760,14 @@
cancelPlayerEvents(true /* keepBufferingGoing */);
if (mAudioPlayer != NULL) {
- mAudioPlayer->pause();
+ if (at_eos) {
+ // If we played the audio stream to completion we
+ // want to make sure that all samples remaining in the audio
+ // track's queue are played out.
+ mAudioPlayer->pause(true /* playPendingSamples */);
+ } else {
+ mAudioPlayer->pause();
+ }
}
mFlags &= ~PLAYING;
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 4d69dd3..a5341e3 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -1838,8 +1838,31 @@
case OMX_EventPortSettingsChanged:
{
+ CODEC_LOGV("OMX_EventPortSettingsChanged(port=%ld, data2=0x%08lx)",
+ data1, data2);
+
if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
onPortSettingsChanged(data1);
+ } else if (data1 == kPortIndexOutput
+ && data2 == OMX_IndexConfigCommonOutputCrop) {
+
+ OMX_CONFIG_RECTTYPE rect;
+ rect.nPortIndex = kPortIndexOutput;
+ InitOMXParams(&rect);
+
+ status_t err =
+ mOMX->getConfig(
+ mNode, OMX_IndexConfigCommonOutputCrop,
+ &rect, sizeof(rect));
+
+ if (err == OK) {
+ CODEC_LOGV(
+ "output crop (%ld, %ld, %ld, %ld)",
+ rect.nLeft, rect.nTop, rect.nWidth, rect.nHeight);
+ } else {
+ CODEC_LOGE("getConfig(OMX_IndexConfigCommonOutputCrop) "
+ "returned error 0x%08x", err);
+ }
}
break;
}
diff --git a/media/libstagefright/colorconversion/SoftwareRenderer.cpp b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
index c204a94..662a84a 100644
--- a/media/libstagefright/colorconversion/SoftwareRenderer.cpp
+++ b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
@@ -48,6 +48,9 @@
LOGI("display = %d x %d, decoded = %d x %d",
mDisplayWidth, mDisplayHeight, mDecodedWidth, mDecodedHeight);
+ mDecodedWidth = mDisplayWidth;
+ mDecodedHeight = mDisplayHeight;
+
int halFormat;
switch (mColorFormat) {
#if HAS_YCBCR420_SP_ADRENO
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index db98253..e04a24d 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -223,7 +223,7 @@
status_t setDataSource_l(const sp<MediaExtractor> &extractor);
void reset_l();
status_t seekTo_l(int64_t timeUs);
- status_t pause_l();
+ status_t pause_l(bool at_eos = false);
void initRenderer_l();
void notifyVideoSize_l();
void seekAudioIfNecessary_l();
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_default.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_default.png
new file mode 100644
index 0000000..bf33c946
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_default.png
Binary files differ
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar.xml b/packages/SystemUI/res/layout-xlarge/status_bar.xml
index 6aee011..494dfa8 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar.xml
@@ -28,11 +28,11 @@
>
<ImageView
- class="com.android.systemui.statusbar.tablet.NotificationIconArea$MoreView"
android:id="@+id/expand"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_sysbar_open"
+ android:background="@drawable/ic_sysbar_icon_bg"
android:paddingLeft="6dip"
android:onClick="notificationIconsClicked"
/>
@@ -100,8 +100,18 @@
android:background="@drawable/sysbar_hidenotification_handle"
android:layout_marginLeft="8dip"
/>
+ <com.android.systemui.statusbar.tablet.InputMethodButton
+ android:id="@+id/imeButton"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_marginLeft="8dip"
+ android:src="@drawable/ic_sysbar_ime_default"
+ android:background="@drawable/ic_sysbar_icon_bg"
+ android:visibility="visible"
+ />
</com.android.systemui.statusbar.tablet.NotificationIconArea>
+
<FrameLayout
android:id="@+id/ticker"
android:layout_width="wrap_content"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java
new file mode 100644
index 0000000..ba682b7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java
@@ -0,0 +1,51 @@
+/*
+ * 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 com.android.systemui.statusbar.tablet;
+
+import android.content.Context;
+import android.util.Slog;
+import android.view.View;
+import android.util.AttributeSet;
+import android.widget.ImageView;
+import android.view.inputmethod.InputMethodManager;
+
+import com.android.server.InputMethodManagerService;
+
+public class InputMethodButton extends ImageView {
+
+ // other services we wish to talk to
+ InputMethodManager mImm;
+
+ public InputMethodButton(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ // IME hookup
+ mImm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+
+ // TODO: read the current icon & visibility state directly from the service
+
+ // TODO: register for notifications about changes to visibility & subtype from service
+
+ setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mImm.showInputMethodSubtypePicker();
+ }
+ });
+ }
+}
+
diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java
index 3583ab9..1383354 100644
--- a/policy/src/com/android/internal/policy/impl/LockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/LockScreen.java
@@ -214,6 +214,9 @@
}
class WaveViewMethods implements WaveView.OnTriggerListener {
+ private static final int WAIT_FOR_ANIMATION_TIMEOUT = 500;
+ private static final int STAY_ON_WHILE_GRABBED_TIMEOUT = 30000;
+
/** {@inheritDoc} */
public void onTrigger(View v, int whichHandle) {
if (whichHandle == WaveView.OnTriggerListener.CENTER_HANDLE) {
@@ -222,13 +225,17 @@
public void run() {
mCallback.goToUnlockScreen();
}
- }, 500);
+ }, WAIT_FOR_ANIMATION_TIMEOUT);
}
}
/** {@inheritDoc} */
public void onGrabbedStateChange(View v, int grabbedState) {
- mCallback.pokeWakelock();
+ if (grabbedState == WaveView.OnTriggerListener.CENTER_HANDLE) {
+ mCallback.pokeWakelock(STAY_ON_WHILE_GRABBED_TIMEOUT);
+ } else {
+ mCallback.pokeWakelock();
+ }
}
}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index c25df1d..24c9443 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -1504,7 +1504,11 @@
sendCloseSystemWindows();
Intent intent = new Intent(Intent.ACTION_CALL_BUTTON);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- getContext().startActivity(intent);
+ try {
+ getContext().startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ Log.w(TAG, "No activity found for android.intent.action.CALL_BUTTON.");
+ }
}
@Override
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 8527059..cd9b07e 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1715,7 +1715,7 @@
// The first time a track is added we wait
// for all its buffers to be filled before processing it
mAudioMixer->setActiveTrack(track->name());
- if (cblk->framesReady() && (track->isReady() || track->isStopped()) &&
+ if (cblk->framesReady() && track->isReady() &&
!track->isPaused() && !track->isTerminated())
{
//LOGV("track %d u=%08x, s=%08x [OK] on thread %p", track->name(), cblk->user, cblk->server, this);
@@ -2231,7 +2231,7 @@
// The first time a track is added we wait
// for all its buffers to be filled before processing it
- if (cblk->framesReady() && (track->isReady() || track->isStopped()) &&
+ if (cblk->framesReady() && track->isReady() &&
!track->isPaused() && !track->isTerminated())
{
//LOGV("track %d u=%08x, s=%08x [OK]", track->name(), cblk->user, cblk->server);
@@ -3039,7 +3039,7 @@
}
bool AudioFlinger::PlaybackThread::Track::isReady() const {
- if (mFillingUpStatus != FS_FILLING) return true;
+ if (mFillingUpStatus != FS_FILLING || isStopped() || isPausing()) return true;
if (mCblk->framesReady() >= mCblk->frameCount ||
(mCblk->flags & CBLK_FORCEREADY_MSK)) {
diff --git a/services/java/com/android/server/BatteryService.java b/services/java/com/android/server/BatteryService.java
index e6c32d9..a8ccfc0 100644
--- a/services/java/com/android/server/BatteryService.java
+++ b/services/java/com/android/server/BatteryService.java
@@ -99,6 +99,7 @@
private int mBatteryTemperature;
private String mBatteryTechnology;
private boolean mBatteryLevelCritical;
+ private boolean mInvalidCharger;
private int mLastBatteryStatus;
private int mLastBatteryHealth;
@@ -107,6 +108,7 @@
private int mLastBatteryVoltage;
private int mLastBatteryTemperature;
private boolean mLastBatteryLevelCritical;
+ private boolean mLastInvalidCharger;
private int mLowBatteryWarningLevel;
private int mLowBatteryCloseWarningLevel;
@@ -128,7 +130,12 @@
mLowBatteryCloseWarningLevel = mContext.getResources().getInteger(
com.android.internal.R.integer.config_lowBatteryCloseWarningLevel);
- mUEventObserver.startObserving("SUBSYSTEM=power_supply");
+ mPowerSupplyObserver.startObserving("SUBSYSTEM=power_supply");
+
+ // watch for invalid charger messages if the invalid_charger switch exists
+ if (new File("/sys/devices/virtual/switch/invalid_charger/state").exists()) {
+ mInvalidChargerObserver.startObserving("DEVPATH=/devices/virtual/switch/invalid_charger");
+ }
// set initial status
update();
@@ -162,13 +169,24 @@
return mPlugType;
}
- private UEventObserver mUEventObserver = new UEventObserver() {
+ private UEventObserver mPowerSupplyObserver = new UEventObserver() {
@Override
public void onUEvent(UEventObserver.UEvent event) {
update();
}
};
+ private UEventObserver mInvalidChargerObserver = new UEventObserver() {
+ @Override
+ public void onUEvent(UEventObserver.UEvent event) {
+ boolean invalidCharger = "1".equals(event.get("SWITCH_STATE"));
+ if (mInvalidCharger != invalidCharger) {
+ mInvalidCharger = invalidCharger;
+ update();
+ }
+ }
+ };
+
// returns battery level as a percentage
final int getBatteryLevel() {
return mBatteryLevel;
@@ -237,7 +255,8 @@
mBatteryLevel != mLastBatteryLevel ||
mPlugType != mLastPlugType ||
mBatteryVoltage != mLastBatteryVoltage ||
- mBatteryTemperature != mLastBatteryTemperature) {
+ mBatteryTemperature != mLastBatteryTemperature ||
+ mInvalidCharger != mLastInvalidCharger) {
if (mPlugType != mLastPlugType) {
if (mLastPlugType == BATTERY_PLUGGED_NONE) {
@@ -334,6 +353,7 @@
mLastBatteryVoltage = mBatteryVoltage;
mLastBatteryTemperature = mBatteryTemperature;
mLastBatteryLevelCritical = mBatteryLevelCritical;
+ mLastInvalidCharger = mInvalidCharger;
}
}
@@ -355,6 +375,7 @@
intent.putExtra(BatteryManager.EXTRA_VOLTAGE, mBatteryVoltage);
intent.putExtra(BatteryManager.EXTRA_TEMPERATURE, mBatteryTemperature);
intent.putExtra(BatteryManager.EXTRA_TECHNOLOGY, mBatteryTechnology);
+ intent.putExtra(BatteryManager.EXTRA_INVALID_CHARGER, mInvalidCharger);
if (false) {
Slog.d(TAG, "updateBattery level:" + mBatteryLevel +
@@ -364,7 +385,7 @@
" temperature: " + mBatteryTemperature +
" technology: " + mBatteryTechnology +
" AC powered:" + mAcOnline + " USB powered:" + mUsbOnline +
- " icon:" + icon );
+ " icon:" + icon + " invalid charger:" + mInvalidCharger);
}
ActivityManagerNative.broadcastStickyIntent(intent, null);
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 9a5423c..70bde01 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -25,6 +25,7 @@
import com.android.internal.view.IInputMethodManager;
import com.android.internal.view.IInputMethodSession;
import com.android.internal.view.InputBindResult;
+import com.android.internal.view.InputMethodAndSubtypeEnabler;
import com.android.server.StatusBarManagerService;
@@ -83,6 +84,7 @@
import java.text.Collator;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
@@ -97,6 +99,7 @@
static final int MSG_SHOW_IM_PICKER = 1;
static final int MSG_SHOW_IM_SUBTYPE_PICKER = 2;
+ static final int MSG_SHOW_IM_SUBTYPE_ENABLER = 3;
static final int MSG_UNBIND_INPUT = 1000;
static final int MSG_BIND_INPUT = 1010;
@@ -1225,7 +1228,7 @@
synchronized (mMethodMap) {
if (mCurClient == null || client == null
|| mCurClient.client.asBinder() != client.asBinder()) {
- Slog.w(TAG, "Ignoring showInputMethodDialogFromClient of uid "
+ Slog.w(TAG, "Ignoring showInputMethodPickerFromClient of uid "
+ Binder.getCallingUid() + ": " + client);
}
@@ -1237,13 +1240,26 @@
synchronized (mMethodMap) {
if (mCurClient == null || client == null
|| mCurClient.client.asBinder() != client.asBinder()) {
- Slog.w(TAG, "Ignoring showInputSubtypeMethodDialogFromClient of: " + client);
+ Slog.w(TAG, "Ignoring showInputMethodSubtypePickerFromClient of: " + client);
}
mHandler.sendEmptyMessage(MSG_SHOW_IM_SUBTYPE_PICKER);
}
}
+ public void showInputMethodAndSubtypeEnablerFromClient(
+ IInputMethodClient client, String topId) {
+ // TODO: Handle topId for setting the top position of the list activity
+ synchronized (mMethodMap) {
+ if (mCurClient == null || client == null
+ || mCurClient.client.asBinder() != client.asBinder()) {
+ Slog.w(TAG, "Ignoring showInputMethodAndSubtypeEnablerFromClient of: " + client);
+ }
+
+ mHandler.sendEmptyMessage(MSG_SHOW_IM_SUBTYPE_ENABLER);
+ }
+ }
+
public void setInputMethod(IBinder token, String id) {
setInputMethodWithSubtype(token, id, NOT_A_SUBTYPE_ID);
}
@@ -1336,6 +1352,10 @@
showInputMethodSubtypeMenu();
return true;
+ case MSG_SHOW_IM_SUBTYPE_ENABLER:
+ showInputMethodAndSubtypeEnabler();
+ return true;
+
// ---------------------------------------------------------
case MSG_UNBIND_INPUT:
@@ -1528,6 +1548,14 @@
showInputMethodMenuInternal(true);
}
+ private void showInputMethodAndSubtypeEnabler() {
+ Intent intent = new Intent();
+ intent.setClassName("android", InputMethodAndSubtypeEnabler.class.getCanonicalName());
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+ mContext.startActivity(intent);
+ }
+
private void showInputMethodMenuInternal(boolean showSubtypes) {
if (DEBUG) Slog.v(TAG, "Show switching menu");
@@ -1540,14 +1568,15 @@
int lastInputMethodSubtypeId = getSelectedInputMethodSubtypeId(lastInputMethodId);
if (DEBUG) Slog.v(TAG, "Current IME: " + lastInputMethodId);
- final List<InputMethodInfo> immis = getEnabledInputMethodList();
- ArrayList<Integer> subtypeIds = new ArrayList<Integer>();
-
- if (immis == null) {
- return;
- }
-
synchronized (mMethodMap) {
+ final List<Pair<InputMethodInfo, ArrayList<String>>> immis =
+ mSettings.getEnabledInputMethodAndSubtypeListLocked();
+ ArrayList<Integer> subtypeIds = new ArrayList<Integer>();
+
+ if (immis == null || immis.size() == 0) {
+ return;
+ }
+
hideInputMethodMenuLocked();
int N = immis.size();
@@ -1556,32 +1585,38 @@
new TreeMap<CharSequence, Pair<InputMethodInfo, Integer>>(Collator.getInstance());
for (int i = 0; i < N; ++i) {
- InputMethodInfo property = immis.get(i);
+ InputMethodInfo property = immis.get(i).first;
+ final ArrayList<String> enabledSubtypeIds = immis.get(i).second;
+ HashSet<String> enabledSubtypeSet = new HashSet<String>();
+ for (String s : enabledSubtypeIds) {
+ enabledSubtypeSet.add(s);
+ }
if (property == null) {
continue;
}
- // TODO: Show only enabled subtypes
ArrayList<InputMethodSubtype> subtypes = property.getSubtypes();
CharSequence label = property.loadLabel(pm);
- if (showSubtypes && subtypes.size() > 0) {
+ if (showSubtypes && enabledSubtypeSet.size() > 0) {
for (int j = 0; j < subtypes.size(); ++j) {
InputMethodSubtype subtype = subtypes.get(j);
- CharSequence title;
- int nameResId = subtype.getNameResId();
- int modeResId = subtype.getModeResId();
- if (nameResId != 0) {
- title = pm.getText(property.getPackageName(), nameResId,
- property.getServiceInfo().applicationInfo);
- } else {
- CharSequence language = subtype.getLocale();
- CharSequence mode = modeResId == 0 ? null
- : pm.getText(property.getPackageName(), modeResId,
- property.getServiceInfo().applicationInfo);
- // TODO: Use more friendly Title and UI
- title = label + "," + (mode == null ? "" : mode) + ","
- + (language == null ? "" : language);
+ if (enabledSubtypeSet.contains(String.valueOf(subtype.hashCode()))) {
+ CharSequence title;
+ int nameResId = subtype.getNameResId();
+ int modeResId = subtype.getModeResId();
+ if (nameResId != 0) {
+ title = pm.getText(property.getPackageName(), nameResId,
+ property.getServiceInfo().applicationInfo);
+ } else {
+ CharSequence language = subtype.getLocale();
+ CharSequence mode = modeResId == 0 ? null
+ : pm.getText(property.getPackageName(), modeResId,
+ property.getServiceInfo().applicationInfo);
+ // TODO: Use more friendly Title and UI
+ title = label + "," + (mode == null ? "" : mode) + ","
+ + (language == null ? "" : language);
+ }
+ imMap.put(title, new Pair<InputMethodInfo, Integer>(property, j));
}
- imMap.put(title, new Pair<InputMethodInfo, Integer>(property, j));
}
} else {
imMap.put(label,
@@ -1651,6 +1686,20 @@
}
});
+ if (showSubtypes) {
+ mDialogBuilder.setPositiveButton(com.android.internal.R.string.more_item_label,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ showInputMethodAndSubtypeEnabler();
+ }
+ });
+ }
+ mDialogBuilder.setNegativeButton(com.android.internal.R.string.cancel,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ hideInputMethodMenu();
+ }
+ });
mSwitchingDialog = mDialogBuilder.create();
mSwitchingDialog.getWindow().setType(
WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG);
@@ -1837,6 +1886,12 @@
getEnabledInputMethodsAndSubtypeListLocked());
}
+ public List<Pair<InputMethodInfo, ArrayList<String>>>
+ getEnabledInputMethodAndSubtypeListLocked() {
+ return createEnabledInputMethodAndSubtypeListLocked(
+ getEnabledInputMethodsAndSubtypeListLocked());
+ }
+
// At the initial boot, the settings for input methods are not set,
// so we need to enable IME in that case.
public void enableAllIMEsIfThereIsNoEnabledIME() {
@@ -1933,6 +1988,20 @@
return res;
}
+ private List<Pair<InputMethodInfo, ArrayList<String>>>
+ createEnabledInputMethodAndSubtypeListLocked(
+ List<Pair<String, ArrayList<String>>> imsList) {
+ final ArrayList<Pair<InputMethodInfo, ArrayList<String>>> res
+ = new ArrayList<Pair<InputMethodInfo, ArrayList<String>>>();
+ for (Pair<String, ArrayList<String>> ims : imsList) {
+ InputMethodInfo info = mMethodMap.get(ims.first);
+ if (info != null) {
+ res.add(new Pair<InputMethodInfo, ArrayList<String>>(info, ims.second));
+ }
+ }
+ return res;
+ }
+
private void putEnabledInputMethodsStr(String str) {
Settings.Secure.putString(mResolver, Settings.Secure.ENABLED_INPUT_METHODS, str);
mEnabledInputMethodsStrCache = str;
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index c4d2d4d..bcf1b96 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -140,7 +140,6 @@
private static final boolean DEBUG_PREFERRED = false;
private static final boolean DEBUG_UPGRADE = false;
private static final boolean DEBUG_INSTALL = false;
- private static final boolean DEBUG_NATIVE = false;
private static final boolean MULTIPLE_APPLICATION_UIDS = true;
private static final int RADIO_UID = Process.PHONE_UID;
@@ -3241,8 +3240,6 @@
}
}
- pkg.applicationInfo.nativeLibraryDir = pkgSetting.nativeLibraryPathString;
-
/*
* Set the data dir to the default "/data/data/<package name>/lib"
* if we got here without anyone telling us different (e.g., apps
@@ -3252,10 +3249,14 @@
* This happens during an upgrade from a package settings file that
* doesn't have a native library path attribute at all.
*/
- if (pkgSetting.nativeLibraryPathString == null && pkg.applicationInfo.dataDir != null) {
- final String nativeLibraryPath = new File(dataPath, LIB_DIR_NAME).getPath();
- pkg.applicationInfo.nativeLibraryDir = nativeLibraryPath;
- pkgSetting.nativeLibraryPathString = nativeLibraryPath;
+ if (pkg.applicationInfo.nativeLibraryDir == null && pkg.applicationInfo.dataDir != null) {
+ if (pkgSetting.nativeLibraryPathString == null) {
+ final String nativeLibraryPath = new File(dataPath, LIB_DIR_NAME).getPath();
+ pkg.applicationInfo.nativeLibraryDir = nativeLibraryPath;
+ pkgSetting.nativeLibraryPathString = nativeLibraryPath;
+ } else {
+ pkg.applicationInfo.nativeLibraryDir = pkgSetting.nativeLibraryPathString;
+ }
}
pkgSetting.uidError = uidError;
@@ -3274,10 +3275,23 @@
* In other words, we're going to unpack the binaries
* only for non-system apps and system app upgrades.
*/
- if ((!isSystemApp(pkg) || isUpdatedSystemApp(pkg)) && !isExternal(pkg)) {
- Log.i(TAG, path + " changed; unpacking");
- File sharedLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
- NativeLibraryHelper.copyNativeBinariesLI(scanFile, sharedLibraryDir);
+ if (pkg.applicationInfo.nativeLibraryDir != null) {
+ final File sharedLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
+ if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
+ /*
+ * Upgrading from a previous version of the OS sometimes
+ * leaves native libraries in the /data/data/<app>/lib
+ * directory for system apps even when they shouldn't be.
+ * Recent changes in the JNI library search path
+ * necessitates we remove those to match previous behavior.
+ */
+ if (NativeLibraryHelper.removeNativeBinariesFromDirLI(sharedLibraryDir)) {
+ Log.i(TAG, "removed obsolete native libraries for system package " + path);
+ }
+ } else if (!isExternal(pkg)) {
+ Log.i(TAG, path + " changed; unpacking");
+ NativeLibraryHelper.copyNativeBinariesLI(scanFile, sharedLibraryDir);
+ }
}
pkg.mScanPath = path;
@@ -8051,7 +8065,7 @@
if (p != null) {
if (!p.codePath.equals(codePath)) {
// Check to see if its a disabled system app
- if((p != null) && ((p.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0)) {
+ if ((p.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
// This is an updated system app with versions in both system
// and data partition. Just let the most recent version
// take precedence.
@@ -8062,6 +8076,13 @@
// let's log a message about it.
Slog.i(TAG, "Package " + name + " codePath changed from " + p.codePath
+ " to " + codePath + "; Retaining data and using new");
+ /*
+ * Since we've changed paths, we need to prefer the new
+ * native library path over the one stored in the
+ * package settings since we might have moved from
+ * internal to external storage or vice versa.
+ */
+ p.nativeLibraryPathString = nativeLibraryPathString;
}
}
if (p.sharedUser != sharedUser) {
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 29a9a7e..5386a1a 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -220,6 +220,7 @@
private Sensor mLightSensor;
private boolean mLightSensorEnabled;
private float mLightSensorValue = -1;
+ private boolean mProxIgnoredBecauseScreenTurnedOff = false;
private int mHighestLightSensorValue = -1;
private float mLightSensorPendingValue = -1;
private int mLightSensorScreenBrightness = -1;
@@ -252,7 +253,7 @@
// could be either static or controllable at runtime
private static final boolean mSpew = false;
- private static final boolean mDebugProximitySensor = (true || mSpew);
+ private static final boolean mDebugProximitySensor = (false || mSpew);
private static final boolean mDebugLightSensor = (false || mSpew);
private native void nativeInit();
@@ -638,7 +639,8 @@
int n = flags & LOCK_MASK;
return n == PowerManager.FULL_WAKE_LOCK
|| n == PowerManager.SCREEN_BRIGHT_WAKE_LOCK
- || n == PowerManager.SCREEN_DIM_WAKE_LOCK;
+ || n == PowerManager.SCREEN_DIM_WAKE_LOCK
+ || n == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK;
}
void enforceWakeSourcePermission(int uid, int pid) {
@@ -778,25 +780,33 @@
// set it to whatever they want. otherwise, we modulate that
// by the current state so we never turn it more on than
// it already is.
- if ((wl.flags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {
- int oldWakeLockState = mWakeLockState;
- mWakeLockState = mLocks.reactivateScreenLocksLocked();
- if (mSpew) {
- Slog.d(TAG, "wakeup here mUserState=0x" + Integer.toHexString(mUserState)
- + " mWakeLockState=0x"
- + Integer.toHexString(mWakeLockState)
- + " previous wakeLockState=0x" + Integer.toHexString(oldWakeLockState));
+ if ((flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) {
+ mProximityWakeLockCount++;
+ if (mProximityWakeLockCount == 1) {
+ enableProximityLockLocked();
}
} else {
- if (mSpew) {
- Slog.d(TAG, "here mUserState=0x" + Integer.toHexString(mUserState)
- + " mLocks.gatherState()=0x"
- + Integer.toHexString(mLocks.gatherState())
- + " mWakeLockState=0x" + Integer.toHexString(mWakeLockState));
+ if ((wl.flags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {
+ int oldWakeLockState = mWakeLockState;
+ mWakeLockState = mLocks.reactivateScreenLocksLocked();
+ if (mSpew) {
+ Slog.d(TAG, "wakeup here mUserState=0x" + Integer.toHexString(mUserState)
+ + " mWakeLockState=0x"
+ + Integer.toHexString(mWakeLockState)
+ + " previous wakeLockState=0x"
+ + Integer.toHexString(oldWakeLockState));
+ }
+ } else {
+ if (mSpew) {
+ Slog.d(TAG, "here mUserState=0x" + Integer.toHexString(mUserState)
+ + " mLocks.gatherState()=0x"
+ + Integer.toHexString(mLocks.gatherState())
+ + " mWakeLockState=0x" + Integer.toHexString(mWakeLockState));
+ }
+ mWakeLockState = (mUserState | mWakeLockState) & mLocks.gatherState();
}
- mWakeLockState = (mUserState | mWakeLockState) & mLocks.gatherState();
+ setPowerState(mWakeLockState | mUserState);
}
- setPowerState(mWakeLockState | mUserState);
}
else if ((flags & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK) {
if (newlock) {
@@ -806,11 +816,6 @@
}
}
Power.acquireWakeLock(Power.PARTIAL_WAKE_LOCK,PARTIAL_NAME);
- } else if ((flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) {
- mProximityWakeLockCount++;
- if (mProximityWakeLockCount == 1) {
- enableProximityLockLocked();
- }
}
if (diffsource) {
@@ -868,12 +873,27 @@
}
if (isScreenLock(wl.flags)) {
- mWakeLockState = mLocks.gatherState();
- // goes in the middle to reduce flicker
- if ((wl.flags & PowerManager.ON_AFTER_RELEASE) != 0) {
- userActivity(SystemClock.uptimeMillis(), -1, false, OTHER_EVENT, false);
+ if ((wl.flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) {
+ mProximityWakeLockCount--;
+ if (mProximityWakeLockCount == 0) {
+ if (mProximitySensorActive &&
+ ((flags & PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE) != 0)) {
+ // wait for proximity sensor to go negative before disabling sensor
+ if (mDebugProximitySensor) {
+ Slog.d(TAG, "waiting for proximity sensor to go negative");
+ }
+ } else {
+ disableProximityLockLocked();
+ }
+ }
+ } else {
+ mWakeLockState = mLocks.gatherState();
+ // goes in the middle to reduce flicker
+ if ((wl.flags & PowerManager.ON_AFTER_RELEASE) != 0) {
+ userActivity(SystemClock.uptimeMillis(), -1, false, OTHER_EVENT, false);
+ }
+ setPowerState(mWakeLockState | mUserState);
}
- setPowerState(mWakeLockState | mUserState);
}
else if ((wl.flags & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK) {
mPartialCount--;
@@ -881,19 +901,6 @@
if (LOG_PARTIAL_WL) EventLog.writeEvent(EventLogTags.POWER_PARTIAL_WAKE_STATE, 0, wl.tag);
Power.releaseWakeLock(PARTIAL_NAME);
}
- } else if ((wl.flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) {
- mProximityWakeLockCount--;
- if (mProximityWakeLockCount == 0) {
- if (mProximitySensorActive &&
- ((flags & PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE) != 0)) {
- // wait for proximity sensor to go negative before disabling sensor
- if (mDebugProximitySensor) {
- Slog.d(TAG, "waiting for proximity sensor to go negative");
- }
- } else {
- disableProximityLockLocked();
- }
- }
}
// Unlink the lock from the binder.
wl.binder.unlinkToDeath(wl, 0);
@@ -2433,11 +2440,23 @@
mWakeLockState = SCREEN_OFF;
int N = mLocks.size();
int numCleared = 0;
+ boolean proxLock = false;
for (int i=0; i<N; i++) {
WakeLock wl = mLocks.get(i);
if (isScreenLock(wl.flags)) {
- mLocks.get(i).activated = false;
- numCleared++;
+ if (((wl.flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)
+ && reason == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR) {
+ proxLock = true;
+ } else {
+ mLocks.get(i).activated = false;
+ numCleared++;
+ }
+ }
+ }
+ if (!proxLock) {
+ mProxIgnoredBecauseScreenTurnedOff = true;
+ if (mDebugProximitySensor) {
+ Slog.d(TAG, "setting mProxIgnoredBecauseScreenTurnedOff");
}
}
EventLog.writeEvent(EventLogTags.POWER_SLEEP_REQUESTED, numCleared);
@@ -2629,6 +2648,11 @@
result |= wl.minState;
}
}
+ if (mDebugProximitySensor) {
+ Slog.d(TAG, "reactivateScreenLocksLocked mProxIgnoredBecauseScreenTurnedOff="
+ + mProxIgnoredBecauseScreenTurnedOff);
+ }
+ mProxIgnoredBecauseScreenTurnedOff = false;
return result;
}
}
@@ -2788,7 +2812,13 @@
}
if (mProximitySensorActive) {
mProximitySensorActive = false;
- forceUserActivityLocked();
+ if (mDebugProximitySensor) {
+ Slog.d(TAG, "disableProximityLockLocked mProxIgnoredBecauseScreenTurnedOff="
+ + mProxIgnoredBecauseScreenTurnedOff);
+ }
+ if (!mProxIgnoredBecauseScreenTurnedOff) {
+ forceUserActivityLocked();
+ }
}
}
}
@@ -2802,15 +2832,27 @@
return;
}
if (active) {
- goToSleepLocked(SystemClock.uptimeMillis(),
- WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR);
+ if (mDebugProximitySensor) {
+ Slog.d(TAG, "b mProxIgnoredBecauseScreenTurnedOff="
+ + mProxIgnoredBecauseScreenTurnedOff);
+ }
+ if (!mProxIgnoredBecauseScreenTurnedOff) {
+ goToSleepLocked(SystemClock.uptimeMillis(),
+ WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR);
+ }
mProximitySensorActive = true;
} else {
// proximity sensor negative events trigger as user activity.
// temporarily set mUserActivityAllowed to true so this will work
// even when the keyguard is on.
mProximitySensorActive = false;
- forceUserActivityLocked();
+ if (mDebugProximitySensor) {
+ Slog.d(TAG, "b mProxIgnoredBecauseScreenTurnedOff="
+ + mProxIgnoredBecauseScreenTurnedOff);
+ }
+ if (!mProxIgnoredBecauseScreenTurnedOff) {
+ forceUserActivityLocked();
+ }
if (mProximityWakeLockCount == 0) {
// disable sensor if we have no listeners left after proximity negative
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index d008c90..3084c16 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -2998,84 +2998,6 @@
}
}
- final void decPersistentCountLocked(ProcessRecord app) {
- app.persistentActivities--;
- if (app.persistentActivities > 0) {
- // Still more of 'em...
- return;
- }
- if (app.persistent) {
- // Ah, but the application itself is persistent. Whatever!
- return;
- }
-
- // App is no longer persistent... make sure it and the ones
- // following it in the LRU list have the correc oom_adj.
- updateOomAdjLocked();
- }
-
- public void setPersistent(IBinder token, boolean isPersistent) {
- if (checkCallingPermission(android.Manifest.permission.PERSISTENT_ACTIVITY)
- != PackageManager.PERMISSION_GRANTED) {
- String msg = "Permission Denial: setPersistent() from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid()
- + " requires " + android.Manifest.permission.PERSISTENT_ACTIVITY;
- Slog.w(TAG, msg);
- throw new SecurityException(msg);
- }
-
- synchronized(this) {
- int index = mMainStack.indexOfTokenLocked(token);
- if (index < 0) {
- return;
- }
- ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
- ProcessRecord app = r.app;
-
- if (localLOGV) Slog.v(
- TAG, "Setting persistence " + isPersistent + ": " + r);
-
- if (isPersistent) {
- if (r.persistent) {
- // Okay okay, I heard you already!
- if (localLOGV) Slog.v(TAG, "Already persistent!");
- return;
- }
- r.persistent = true;
- app.persistentActivities++;
- if (localLOGV) Slog.v(TAG, "Num persistent now: " + app.persistentActivities);
- if (app.persistentActivities > 1) {
- // We aren't the first...
- if (localLOGV) Slog.v(TAG, "Not the first!");
- return;
- }
- if (app.persistent) {
- // This would be redundant.
- if (localLOGV) Slog.v(TAG, "App is persistent!");
- return;
- }
-
- // App is now persistent... make sure it and the ones
- // following it now have the correct oom_adj.
- final long origId = Binder.clearCallingIdentity();
- updateOomAdjLocked();
- Binder.restoreCallingIdentity(origId);
-
- } else {
- if (!r.persistent) {
- // Okay okay, I heard you already!
- return;
- }
- r.persistent = false;
- final long origId = Binder.clearCallingIdentity();
- decPersistentCountLocked(app);
- Binder.restoreCallingIdentity(origId);
-
- }
- }
- }
-
public boolean clearApplicationUserData(final String packageName,
final IPackageDataObserver observer) {
int uid = Binder.getCallingUid();
@@ -11765,11 +11687,6 @@
adj = FOREGROUND_APP_ADJ;
schedGroup = Process.THREAD_GROUP_DEFAULT;
app.adjType = "instrumentation";
- } else if (app.persistentActivities > 0) {
- // Special persistent activities... shouldn't be used these days.
- adj = FOREGROUND_APP_ADJ;
- schedGroup = Process.THREAD_GROUP_DEFAULT;
- app.adjType = "persistent";
} else if (app.curReceiver != null ||
(mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
// An app that is currently receiving a broadcast also
@@ -12493,8 +12410,7 @@
final ProcessRecord app = mLruProcesses.get(i);
if (app.persistent || app.services.size() != 0
- || app.curReceiver != null
- || app.persistentActivities > 0) {
+ || app.curReceiver != null) {
// Don't count processes holding services against our
// maximum process count.
if (localLOGV) Slog.v(
@@ -12559,8 +12475,7 @@
// Quit the application only if we have a state saved for
// all of its activities.
boolean canQuit = !app.persistent && app.curReceiver == null
- && app.services.size() == 0
- && app.persistentActivities == 0;
+ && app.services.size() == 0;
int NUMA = app.activities.size();
int j;
if (Config.LOGV) Slog.v(
@@ -12624,7 +12539,7 @@
// We can finish this one if we have its icicle saved and
// it is not persistent.
if ((r.haveState || !r.stateNotNeeded) && !r.visible
- && r.stopped && !r.persistent && !r.finishing) {
+ && r.stopped && !r.finishing) {
final int origSize = mMainStack.mLRUActivities.size();
r.stack.destroyActivityLocked(r, true);
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index 6bd89cc..47be6a2 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -96,7 +96,6 @@
int configChangeFlags; // which config values have changed
boolean keysPaused; // has key dispatching been paused for it?
boolean inHistory; // are we in the history stack?
- boolean persistent; // requested to be persistent?
int launchMode; // the launch mode activity attribute.
boolean visible; // does this activity's window need to be shown?
boolean waitingVisible; // true if waiting for a new act to become vis
@@ -161,7 +160,6 @@
pw.print(" finishing="); pw.println(finishing);
pw.print(prefix); pw.print("keysPaused="); pw.print(keysPaused);
pw.print(" inHistory="); pw.print(inHistory);
- pw.print(" persistent="); pw.print(persistent);
pw.print(" immersive="); pw.print(immersive);
pw.print(" launchMode="); pw.println(launchMode);
pw.print(prefix); pw.print("fullscreen="); pw.print(fullscreen);
@@ -215,7 +213,6 @@
configDestroy = false;
keysPaused = false;
inHistory = false;
- persistent = false;
visible = true;
waitingVisible = false;
nowVisible = false;
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 9ed1242..016ddcd 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -3151,9 +3151,6 @@
mService.mHandler.sendEmptyMessage(
ActivityManagerService.CANCEL_HEAVY_NOTIFICATION_MSG);
}
- if (r.persistent) {
- mService.decPersistentCountLocked(r.app);
- }
if (r.app.activities.size() == 0) {
// No longer have activities, so update location in
// LRU list.
@@ -3452,54 +3449,49 @@
return true;
}
- // If the activity isn't persistent, there is a chance we will
- // need to restart it.
- if (!r.persistent) {
-
- // Figure out what has changed between the two configurations.
- int changes = oldConfig.diff(newConfig);
- if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
- Slog.v(TAG, "Checking to restart " + r.info.name + ": changed=0x"
- + Integer.toHexString(changes) + ", handles=0x"
- + Integer.toHexString(r.info.configChanges)
- + ", newConfig=" + newConfig);
+ // Figure out what has changed between the two configurations.
+ int changes = oldConfig.diff(newConfig);
+ if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
+ Slog.v(TAG, "Checking to restart " + r.info.name + ": changed=0x"
+ + Integer.toHexString(changes) + ", handles=0x"
+ + Integer.toHexString(r.info.configChanges)
+ + ", newConfig=" + newConfig);
+ }
+ if ((changes&(~r.info.configChanges)) != 0) {
+ // Aha, the activity isn't handling the change, so DIE DIE DIE.
+ r.configChangeFlags |= changes;
+ r.startFreezingScreenLocked(r.app, globalChanges);
+ if (r.app == null || r.app.thread == null) {
+ if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
+ "Switch is destroying non-running " + r);
+ destroyActivityLocked(r, true);
+ } else if (r.state == ActivityState.PAUSING) {
+ // A little annoying: we are waiting for this activity to
+ // finish pausing. Let's not do anything now, but just
+ // flag that it needs to be restarted when done pausing.
+ if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
+ "Switch is skipping already pausing " + r);
+ r.configDestroy = true;
+ return true;
+ } else if (r.state == ActivityState.RESUMED) {
+ // Try to optimize this case: the configuration is changing
+ // and we need to restart the top, resumed activity.
+ // Instead of doing the normal handshaking, just say
+ // "restart!".
+ if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
+ "Switch is restarting resumed " + r);
+ relaunchActivityLocked(r, r.configChangeFlags, true);
+ r.configChangeFlags = 0;
+ } else {
+ if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
+ "Switch is restarting non-resumed " + r);
+ relaunchActivityLocked(r, r.configChangeFlags, false);
+ r.configChangeFlags = 0;
}
- if ((changes&(~r.info.configChanges)) != 0) {
- // Aha, the activity isn't handling the change, so DIE DIE DIE.
- r.configChangeFlags |= changes;
- r.startFreezingScreenLocked(r.app, globalChanges);
- if (r.app == null || r.app.thread == null) {
- if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
- "Switch is destroying non-running " + r);
- destroyActivityLocked(r, true);
- } else if (r.state == ActivityState.PAUSING) {
- // A little annoying: we are waiting for this activity to
- // finish pausing. Let's not do anything now, but just
- // flag that it needs to be restarted when done pausing.
- if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
- "Switch is skipping already pausing " + r);
- r.configDestroy = true;
- return true;
- } else if (r.state == ActivityState.RESUMED) {
- // Try to optimize this case: the configuration is changing
- // and we need to restart the top, resumed activity.
- // Instead of doing the normal handshaking, just say
- // "restart!".
- if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
- "Switch is restarting resumed " + r);
- relaunchActivityLocked(r, r.configChangeFlags, true);
- r.configChangeFlags = 0;
- } else {
- if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
- "Switch is restarting non-resumed " + r);
- relaunchActivityLocked(r, r.configChangeFlags, false);
- r.configChangeFlags = 0;
- }
-
- // All done... tell the caller we weren't able to keep this
- // activity around.
- return false;
- }
+
+ // All done... tell the caller we weren't able to keep this
+ // activity around.
+ return false;
}
// Default case: the activity can handle this new configuration, so
diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java
index 404c6be..353ff6d 100644
--- a/services/java/com/android/server/am/ProcessRecord.java
+++ b/services/java/com/android/server/am/ProcessRecord.java
@@ -115,7 +115,6 @@
Dialog anrDialog; // dialog being displayed due to app not resp.
boolean removed; // has app package been removed from device?
boolean debugging; // was app launched for debugging?
- int persistentActivities; // number of activities that are persistent
boolean waitedForDebugger; // has process show wait for debugger dialog?
Dialog waitDialog; // current wait for debugger dialog
@@ -181,8 +180,7 @@
pw.print(" foregroundServices="); pw.print(foregroundServices);
pw.print(" forcingToForeground="); pw.println(forcingToForeground);
pw.print(prefix); pw.print("persistent="); pw.print(persistent);
- pw.print(" removed="); pw.print(removed);
- pw.print(" persistentActivities="); pw.println(persistentActivities);
+ pw.print(" removed="); pw.println(removed);
pw.print(prefix); pw.print("adjSeq="); pw.print(adjSeq);
pw.print(" lruSeq="); pw.println(lruSeq);
if (!keeping) {
@@ -259,7 +257,6 @@
curAdj = setAdj = -100;
persistent = false;
removed = false;
- persistentActivities = 0;
}
public void setPid(int _pid) {
diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java
index bfac346..0623f5b 100644
--- a/services/java/com/android/server/connectivity/Tethering.java
+++ b/services/java/com/android/server/connectivity/Tethering.java
@@ -113,7 +113,7 @@
private String[] mDnsServers;
private static final String DNS_DEFAULT_SERVER1 = "8.8.8.8";
- private static final String DNS_DEFAULT_SERVER2 = "4.2.2.2";
+ private static final String DNS_DEFAULT_SERVER2 = "8.8.4.4";
// resampled each time we turn on tethering - used as cache for settings/config-val
private boolean mDunRequired; // configuration info - must use DUN apn on 3g
diff --git a/services/java/com/android/server/location/GpsLocationProvider.java b/services/java/com/android/server/location/GpsLocationProvider.java
index 39ce0b6..e9eb4f0 100755
--- a/services/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/java/com/android/server/location/GpsLocationProvider.java
@@ -46,6 +46,10 @@
import android.os.SystemClock;
import android.os.WorkSource;
import android.provider.Settings;
+import android.provider.Telephony.Sms.Intents;
+import android.telephony.TelephonyManager;
+import android.telephony.gsm.GsmCellLocation;
+import android.telephony.SmsMessage;
import android.util.Log;
import android.util.SparseIntArray;
@@ -53,6 +57,9 @@
import com.android.internal.telephony.Phone;
import com.android.internal.location.GpsNetInitiatedHandler;
import com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification;
+import com.android.internal.telephony.GsmAlphabet;
+import com.android.internal.telephony.SmsHeader;
+import com.android.internal.util.HexDump;
import java.io.File;
import java.io.FileInputStream;
@@ -153,6 +160,24 @@
private static final int REMOVE_LISTENER = 9;
private static final int REQUEST_SINGLE_SHOT = 10;
+ // Request setid
+ private static final int AGPS_RIL_REQUEST_SETID_IMSI = 1;
+ private static final int AGPS_RIL_REQUEST_SETID_MSISDN = 2;
+
+ // Request ref location
+ private static final int AGPS_RIL_REQUEST_REFLOC_CELLID = 1;
+ private static final int AGPS_RIL_REQUEST_REFLOC_MAC = 2;
+
+ // ref. location info
+ private static final int AGPS_REF_LOCATION_TYPE_GSM_CELLID = 1;
+ private static final int AGPS_REF_LOCATION_TYPE_UMTS_CELLID = 2;
+ private static final int AGPS_REG_LOCATION_TYPE_MAC = 3;
+
+ // set id info
+ private static final int AGPS_SETID_TYPE_NONE = 0;
+ private static final int AGPS_SETID_TYPE_IMSI = 1;
+ private static final int AGPS_SETID_TYPE_MSISDN = 2;
+
private static final String PROPERTIES_FILE = "/etc/gps.conf";
private int mLocationFlags = LOCATION_INVALID;
@@ -328,10 +353,27 @@
} else if (action.equals(ALARM_TIMEOUT)) {
if (DEBUG) Log.d(TAG, "ALARM_TIMEOUT");
hibernate();
- }
+ } else if (action.equals(Intents.DATA_SMS_RECEIVED_ACTION)) {
+ checkSmsSuplInit(intent);
+ } else if (action.equals(Intents.WAP_PUSH_RECEIVED_ACTION)) {
+ checkWapSuplInit(intent);
+ }
}
};
+ private void checkSmsSuplInit(Intent intent) {
+ SmsMessage[] messages = Intents.getMessagesFromIntent(intent);
+ for (int i=0; i <messages.length; i++) {
+ byte[] supl_init = messages[i].getUserData();
+ native_agps_ni_message(supl_init,supl_init.length);
+ }
+ }
+
+ private void checkWapSuplInit(Intent intent) {
+ byte[] supl_init = (byte[]) intent.getExtra("data");
+ native_agps_ni_message(supl_init,supl_init.length);
+ }
+
public static boolean isSupported() {
return native_is_supported();
}
@@ -352,6 +394,21 @@
mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0);
mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0);
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(Intents.DATA_SMS_RECEIVED_ACTION);
+ intentFilter.addDataScheme("sms");
+ intentFilter.addDataAuthority("localhost","7275");
+ context.registerReceiver(mBroadcastReciever, intentFilter);
+
+ intentFilter = new IntentFilter();
+ intentFilter.addAction(Intents.WAP_PUSH_RECEIVED_ACTION);
+ try {
+ intentFilter.addDataType("application/vnd.omaloc-supl-init");
+ } catch (IntentFilter.MalformedMimeTypeException e) {
+ Log.w(TAG, "Malformed SUPL init mime type");
+ }
+ context.registerReceiver(mBroadcastReciever, intentFilter);
+
mConnMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
// Battery statistics service to be notified when GPS turns on or off
@@ -1255,22 +1312,20 @@
//=============================================================
// NI Client support
- //=============================================================
+ //=============================================================
private final INetInitiatedListener mNetInitiatedListener = new INetInitiatedListener.Stub() {
- // Sends a response for an NI reqeust to HAL.
- public boolean sendNiResponse(int notificationId, int userResponse)
- {
- // TODO Add Permission check
-
- StringBuilder extrasBuf = new StringBuilder();
+ // Sends a response for an NI reqeust to HAL.
+ public boolean sendNiResponse(int notificationId, int userResponse)
+ {
+ // TODO Add Permission check
- if (DEBUG) Log.d(TAG, "sendNiResponse, notifId: " + notificationId +
- ", response: " + userResponse);
-
- native_send_ni_response(notificationId, userResponse);
-
- return true;
- }
+ StringBuilder extrasBuf = new StringBuilder();
+
+ if (DEBUG) Log.d(TAG, "sendNiResponse, notifId: " + notificationId +
+ ", response: " + userResponse);
+ native_send_ni_response(notificationId, userResponse);
+ return true;
+ }
};
public INetInitiatedListener getNetInitiatedListener() {
@@ -1278,70 +1333,132 @@
}
// Called by JNI function to report an NI request.
- @SuppressWarnings("deprecation")
- public void reportNiNotification(
- int notificationId,
- int niType,
- int notifyFlags,
- int timeout,
- int defaultResponse,
- String requestorId,
- String text,
- int requestorIdEncoding,
- int textEncoding,
- String extras // Encoded extra data
+ public void reportNiNotification(
+ int notificationId,
+ int niType,
+ int notifyFlags,
+ int timeout,
+ int defaultResponse,
+ String requestorId,
+ String text,
+ int requestorIdEncoding,
+ int textEncoding,
+ String extras // Encoded extra data
)
- {
- Log.i(TAG, "reportNiNotification: entered");
- Log.i(TAG, "notificationId: " + notificationId +
- ", niType: " + niType +
- ", notifyFlags: " + notifyFlags +
- ", timeout: " + timeout +
- ", defaultResponse: " + defaultResponse);
-
- Log.i(TAG, "requestorId: " + requestorId +
- ", text: " + text +
- ", requestorIdEncoding: " + requestorIdEncoding +
- ", textEncoding: " + textEncoding);
-
- GpsNiNotification notification = new GpsNiNotification();
-
- notification.notificationId = notificationId;
- notification.niType = niType;
- notification.needNotify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_NOTIFY) != 0;
- notification.needVerify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_VERIFY) != 0;
- notification.privacyOverride = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_PRIVACY_OVERRIDE) != 0;
- notification.timeout = timeout;
- notification.defaultResponse = defaultResponse;
- notification.requestorId = requestorId;
- notification.text = text;
- notification.requestorIdEncoding = requestorIdEncoding;
- notification.textEncoding = textEncoding;
-
- // Process extras, assuming the format is
- // one of more lines of "key = value"
- Bundle bundle = new Bundle();
-
- if (extras == null) extras = "";
- Properties extraProp = new Properties();
-
- try {
- extraProp.load(new StringBufferInputStream(extras));
- }
- catch (IOException e)
- {
- Log.e(TAG, "reportNiNotification cannot parse extras data: " + extras);
- }
-
- for (Entry<Object, Object> ent : extraProp.entrySet())
- {
- bundle.putString((String) ent.getKey(), (String) ent.getValue());
- }
-
- notification.extras = bundle;
-
- mNIHandler.handleNiNotification(notification);
- }
+ {
+ Log.i(TAG, "reportNiNotification: entered");
+ Log.i(TAG, "notificationId: " + notificationId +
+ ", niType: " + niType +
+ ", notifyFlags: " + notifyFlags +
+ ", timeout: " + timeout +
+ ", defaultResponse: " + defaultResponse);
+
+ Log.i(TAG, "requestorId: " + requestorId +
+ ", text: " + text +
+ ", requestorIdEncoding: " + requestorIdEncoding +
+ ", textEncoding: " + textEncoding);
+
+ GpsNiNotification notification = new GpsNiNotification();
+
+ notification.notificationId = notificationId;
+ notification.niType = niType;
+ notification.needNotify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_NOTIFY) != 0;
+ notification.needVerify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_VERIFY) != 0;
+ notification.privacyOverride = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_PRIVACY_OVERRIDE) != 0;
+ notification.timeout = timeout;
+ notification.defaultResponse = defaultResponse;
+ notification.requestorId = requestorId;
+ notification.text = text;
+ notification.requestorIdEncoding = requestorIdEncoding;
+ notification.textEncoding = textEncoding;
+
+ // Process extras, assuming the format is
+ // one of more lines of "key = value"
+ Bundle bundle = new Bundle();
+
+ if (extras == null) extras = "";
+ Properties extraProp = new Properties();
+
+ try {
+ extraProp.load(new StringBufferInputStream(extras));
+ }
+ catch (IOException e)
+ {
+ Log.e(TAG, "reportNiNotification cannot parse extras data: " + extras);
+ }
+
+ for (Entry<Object, Object> ent : extraProp.entrySet())
+ {
+ bundle.putString((String) ent.getKey(), (String) ent.getValue());
+ }
+
+ notification.extras = bundle;
+
+ mNIHandler.handleNiNotification(notification);
+ }
+
+ /**
+ * Called from native code to request set id info.
+ * We should be careful about receiving null string from the TelephonyManager,
+ * because sending null String to JNI function would cause a crash.
+ */
+
+ private void requestSetID(int flags) {
+ TelephonyManager phone = (TelephonyManager)
+ mContext.getSystemService(Context.TELEPHONY_SERVICE);
+ int type = AGPS_SETID_TYPE_NONE;
+ String data = "";
+
+ if ((flags & AGPS_RIL_REQUEST_SETID_IMSI) == AGPS_RIL_REQUEST_SETID_IMSI) {
+ String data_temp = phone.getSubscriberId();
+ if (data_temp == null) {
+ // This means the framework does not have the SIM card ready.
+ } else {
+ // This means the framework has the SIM card.
+ data = data_temp;
+ type = AGPS_SETID_TYPE_IMSI;
+ }
+ }
+ else if ((flags & AGPS_RIL_REQUEST_SETID_MSISDN) == AGPS_RIL_REQUEST_SETID_MSISDN) {
+ String data_temp = phone.getLine1Number();
+ if (data_temp == null) {
+ // This means the framework does not have the SIM card ready.
+ } else {
+ // This means the framework has the SIM card.
+ data = data_temp;
+ type = AGPS_SETID_TYPE_MSISDN;
+ }
+ }
+ native_agps_set_id(type, data);
+ }
+
+ /**
+ * Called from native code to request reference location info
+ */
+
+ private void requestRefLocation(int flags) {
+ TelephonyManager phone = (TelephonyManager)
+ mContext.getSystemService(Context.TELEPHONY_SERVICE);
+ if (phone.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) {
+ GsmCellLocation gsm_cell = (GsmCellLocation) phone.getCellLocation();
+ if ((gsm_cell != null) && (phone.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM)
+ && (phone.getNetworkOperator().length() > 3)) {
+ int type;
+ int mcc = Integer.parseInt(phone.getNetworkOperator().substring(0,3));
+ int mnc = Integer.parseInt(phone.getNetworkOperator().substring(3));
+ if (phone.getNetworkType() == TelephonyManager.NETWORK_TYPE_UMTS)
+ type = AGPS_REF_LOCATION_TYPE_UMTS_CELLID;
+ else
+ type = AGPS_REF_LOCATION_TYPE_GSM_CELLID;
+ native_agps_set_ref_location_cellid(type, mcc, mnc,
+ gsm_cell.getLac(), gsm_cell.getCid());
+ }
+ else
+ Log.e(TAG,"Error getting cell location info.");
+ }
+ else
+ Log.e(TAG,"CDMA not supported.");
+ }
private void sendMessage(int message, int arg, Object obj) {
// hold a wake lock while messages are pending
@@ -1472,8 +1589,14 @@
private native void native_agps_data_conn_open(String apn);
private native void native_agps_data_conn_closed();
private native void native_agps_data_conn_failed();
+ private native void native_agps_ni_message(byte [] msg, int length);
private native void native_set_agps_server(int type, String hostname, int port);
// Network-initiated (NI) Support
private native void native_send_ni_response(int notificationId, int userResponse);
+
+ // AGPS ril suport
+ private native void native_agps_set_ref_location_cellid(int type, int mcc, int mnc,
+ int lac, int cid);
+ private native void native_agps_set_id(int type, String setid);
}
diff --git a/services/jni/com_android_server_location_GpsLocationProvider.cpp b/services/jni/com_android_server_location_GpsLocationProvider.cpp
index 93068e6..71c7aba 100755
--- a/services/jni/com_android_server_location_GpsLocationProvider.cpp
+++ b/services/jni/com_android_server_location_GpsLocationProvider.cpp
@@ -40,12 +40,15 @@
static jmethodID method_setEngineCapabilities;
static jmethodID method_xtraDownloadRequest;
static jmethodID method_reportNiNotification;
+static jmethodID method_requestRefLocation;
+static jmethodID method_requestSetID;
static const GpsInterface* sGpsInterface = NULL;
static const GpsXtraInterface* sGpsXtraInterface = NULL;
static const AGpsInterface* sAGpsInterface = NULL;
static const GpsNiInterface* sGpsNiInterface = NULL;
static const GpsDebugInterface* sGpsDebugInterface = NULL;
+static const AGpsRilInterface* sAGpsRilInterface = NULL;
// temporary storage for GPS callbacks
static GpsSvStatus sGpsSvStatus;
@@ -193,17 +196,30 @@
create_thread_callback,
};
-static void android_location_GpsLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
- method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(IDDDFFFJ)V");
- method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
- method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V");
- method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II)V");
- method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
- method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
- method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
- method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification", "(IIIIILjava/lang/String;Ljava/lang/String;IILjava/lang/String;)V");
+static void agps_request_set_id(uint32_t flags)
+{
+ LOGD("agps_request_set_id: flags (%d)", flags);
+
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ env->CallVoidMethod(mCallbacksObj, method_requestSetID, flags);
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
}
+static void agps_request_ref_location(uint32_t flags)
+{
+ LOGD("agps_ref_location: flags (%d)", flags);
+
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ env->CallVoidMethod(mCallbacksObj, method_requestRefLocation, flags);
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
+}
+
+AGpsRilCallbacks sAGpsRilCallbacks = {
+ agps_request_set_id,
+ agps_request_ref_location,
+ create_thread_callback,
+};
+
static const GpsInterface* get_gps_interface() {
int err;
hw_module_t* module;
@@ -222,6 +238,64 @@
return interface;
}
+static const AGpsInterface* GetAGpsInterface()
+{
+ if (!sGpsInterface)
+ sGpsInterface = get_gps_interface();
+ if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0)
+ return NULL;
+
+ if (!sAGpsInterface) {
+ sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE);
+ if (sAGpsInterface)
+ sAGpsInterface->init(&sAGpsCallbacks);
+ }
+ return sAGpsInterface;
+}
+
+static const GpsNiInterface* GetNiInterface()
+{
+ if (!sGpsInterface)
+ sGpsInterface = get_gps_interface();
+ if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0)
+ return NULL;
+
+ if (!sGpsNiInterface) {
+ sGpsNiInterface = (const GpsNiInterface*)sGpsInterface->get_extension(GPS_NI_INTERFACE);
+ if (sGpsNiInterface)
+ sGpsNiInterface->init(&sGpsNiCallbacks);
+ }
+ return sGpsNiInterface;
+}
+
+static const AGpsRilInterface* GetAGpsRilInterface()
+{
+ if (!sGpsInterface)
+ sGpsInterface = get_gps_interface();
+ if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0)
+ return NULL;
+
+ if (!sAGpsRilInterface) {
+ sAGpsRilInterface = (const AGpsRilInterface*)sGpsInterface->get_extension(AGPS_RIL_INTERFACE);
+ if (sAGpsRilInterface)
+ sAGpsRilInterface->init(&sAGpsRilCallbacks);
+ }
+ return sAGpsRilInterface;
+}
+
+static void android_location_GpsLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
+ method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(IDDDFFFJ)V");
+ method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
+ method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V");
+ method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II)V");
+ method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
+ method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
+ method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
+ method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification", "(IIIIILjava/lang/String;Ljava/lang/String;IILjava/lang/String;)V");
+ method_requestRefLocation = env->GetMethodID(clazz,"requestRefLocation","(I)V");
+ method_requestSetID = env->GetMethodID(clazz,"requestSetID","(I)V");
+}
+
static jboolean android_location_GpsLocationProvider_is_supported(JNIEnv* env, jclass clazz) {
if (!sGpsInterface)
sGpsInterface = get_gps_interface();
@@ -239,16 +313,6 @@
if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0)
return false;
- if (!sAGpsInterface)
- sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE);
- if (sAGpsInterface)
- sAGpsInterface->init(&sAGpsCallbacks);
-
- if (!sGpsNiInterface)
- sGpsNiInterface = (const GpsNiInterface*)sGpsInterface->get_extension(GPS_NI_INTERFACE);
- if (sGpsNiInterface)
- sGpsNiInterface->init(&sGpsNiCallbacks);
-
if (!sGpsDebugInterface)
sGpsDebugInterface = (const GpsDebugInterface*)sGpsInterface->get_extension(GPS_DEBUG_INTERFACE);
@@ -313,6 +377,64 @@
return num_svs;
}
+static void android_location_GpsLocationProvider_agps_set_reference_location_cellid(JNIEnv* env,
+ jobject obj, jint type, jint mcc, jint mnc, jint lac, jint cid)
+{
+ AGpsRefLocation location;
+ const AGpsRilInterface* interface = GetAGpsRilInterface();
+ if (!interface) {
+ LOGE("no AGPS RIL interface in agps_set_reference_location_cellid");
+ return;
+ }
+
+ switch(type) {
+ case AGPS_REF_LOCATION_TYPE_GSM_CELLID:
+ case AGPS_REF_LOCATION_TYPE_UMTS_CELLID:
+ location.type = type;
+ location.u.cellID.mcc = mcc;
+ location.u.cellID.mnc = mnc;
+ location.u.cellID.lac = lac;
+ location.u.cellID.cid = cid;
+ break;
+ default:
+ LOGE("Neither a GSM nor a UMTS cellid (%s:%d).",__FUNCTION__,__LINE__);
+ return;
+ break;
+ }
+ interface->set_ref_location(&location, sizeof(location));
+}
+
+static void android_location_GpsLocationProvider_agps_send_ni_message(JNIEnv* env,
+ jobject obj, jbyteArray ni_msg, jint size)
+{
+ size_t sz;
+ const AGpsRilInterface* interface = GetAGpsRilInterface();
+ if (!interface) {
+ LOGE("no AGPS RIL interface in send_ni_message");
+ return;
+ }
+ if (size < 0)
+ return;
+ sz = (size_t)size;
+ jbyte* b = env->GetByteArrayElements(ni_msg, 0);
+ interface->ni_message((uint8_t *)b,sz);
+ env->ReleaseByteArrayElements(ni_msg,b,0);
+}
+
+static void android_location_GpsLocationProvider_agps_set_id(JNIEnv *env,
+ jobject obj, jint type, jstring setid_string)
+{
+ const AGpsRilInterface* interface = GetAGpsRilInterface();
+ if (!interface) {
+ LOGE("no AGPS RIL interface in agps_set_id");
+ return;
+ }
+
+ const char *setid = env->GetStringUTFChars(setid_string, NULL);
+ interface->set_set_id(type, setid);
+ env->ReleaseStringUTFChars(setid_string, setid);
+}
+
static jint android_location_GpsLocationProvider_read_nmea(JNIEnv* env, jobject obj,
jbyteArray nmeaArray, jint buffer_size)
{
@@ -363,60 +485,63 @@
static void android_location_GpsLocationProvider_agps_data_conn_open(JNIEnv* env, jobject obj, jstring apn)
{
- if (!sAGpsInterface) {
- sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE);
+ const AGpsInterface* interface = GetAGpsInterface();
+ if (!interface) {
+ LOGE("no AGPS interface in agps_data_conn_open");
+ return;
}
- if (sAGpsInterface) {
- if (apn == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
- return;
- }
- const char *apnStr = env->GetStringUTFChars(apn, NULL);
- sAGpsInterface->data_conn_open(apnStr);
- env->ReleaseStringUTFChars(apn, apnStr);
+ if (apn == NULL) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ return;
}
+ const char *apnStr = env->GetStringUTFChars(apn, NULL);
+ interface->data_conn_open(apnStr);
+ env->ReleaseStringUTFChars(apn, apnStr);
}
static void android_location_GpsLocationProvider_agps_data_conn_closed(JNIEnv* env, jobject obj)
{
- if (!sAGpsInterface) {
- sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE);
+ const AGpsInterface* interface = GetAGpsInterface();
+ if (!interface) {
+ LOGE("no AGPS interface in agps_data_conn_open");
+ return;
}
- if (sAGpsInterface) {
- sAGpsInterface->data_conn_closed();
- }
+ interface->data_conn_closed();
}
static void android_location_GpsLocationProvider_agps_data_conn_failed(JNIEnv* env, jobject obj)
{
- if (!sAGpsInterface) {
- sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE);
+ const AGpsInterface* interface = GetAGpsInterface();
+ if (!interface) {
+ LOGE("no AGPS interface in agps_data_conn_open");
+ return;
}
- if (sAGpsInterface) {
- sAGpsInterface->data_conn_failed();
- }
+ interface->data_conn_failed();
}
static void android_location_GpsLocationProvider_set_agps_server(JNIEnv* env, jobject obj,
jint type, jstring hostname, jint port)
{
- if (!sAGpsInterface) {
- sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE);
+ const AGpsInterface* interface = GetAGpsInterface();
+ if (!interface) {
+ LOGE("no AGPS interface in agps_data_conn_open");
+ return;
}
- if (sAGpsInterface) {
- const char *c_hostname = env->GetStringUTFChars(hostname, NULL);
- sAGpsInterface->set_server(type, c_hostname, port);
- env->ReleaseStringUTFChars(hostname, c_hostname);
- }
+ const char *c_hostname = env->GetStringUTFChars(hostname, NULL);
+ interface->set_server(type, c_hostname, port);
+ env->ReleaseStringUTFChars(hostname, c_hostname);
}
static void android_location_GpsLocationProvider_send_ni_response(JNIEnv* env, jobject obj,
jint notifId, jint response)
{
- if (!sGpsNiInterface)
- sGpsNiInterface = (const GpsNiInterface*)sGpsInterface->get_extension(GPS_NI_INTERFACE);
- if (sGpsNiInterface)
- sGpsNiInterface->respond(notifId, response);
+ const GpsNiInterface* interface = GetNiInterface();
+ if (!interface) {
+ LOGE("no NI interface in send_ni_response");
+ return;
+ }
+
+ interface->respond(notifId, response);
}
static jstring android_location_GpsLocationProvider_get_internal_state(JNIEnv* env, jobject obj)
@@ -452,8 +577,11 @@
{"native_agps_data_conn_open", "(Ljava/lang/String;)V", (void*)android_location_GpsLocationProvider_agps_data_conn_open},
{"native_agps_data_conn_closed", "()V", (void*)android_location_GpsLocationProvider_agps_data_conn_closed},
{"native_agps_data_conn_failed", "()V", (void*)android_location_GpsLocationProvider_agps_data_conn_failed},
+ {"native_agps_set_id","(ILjava/lang/String;)V",(void*)android_location_GpsLocationProvider_agps_set_id},
+ {"native_agps_set_ref_location_cellid","(IIIII)V",(void*)android_location_GpsLocationProvider_agps_set_reference_location_cellid},
{"native_set_agps_server", "(ILjava/lang/String;I)V", (void*)android_location_GpsLocationProvider_set_agps_server},
{"native_send_ni_response", "(II)V", (void*)android_location_GpsLocationProvider_send_ni_response},
+ {"native_agps_ni_message", "([BI)V", (void *)android_location_GpsLocationProvider_agps_send_ni_message},
{"native_get_internal_state", "()Ljava/lang/String;", (void*)android_location_GpsLocationProvider_get_internal_state},
};
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index ff887e4..4af274b 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -84,7 +84,9 @@
status_t HWComposer::commit() const {
int err = mHwc->set(mHwc, mDpy, mSur, mList);
- mList->flags &= ~HWC_GEOMETRY_CHANGED;
+ if (mList) {
+ mList->flags &= ~HWC_GEOMETRY_CHANGED;
+ }
return (status_t)err;
}
diff --git a/telephony/java/com/android/internal/telephony/CallManager.java b/telephony/java/com/android/internal/telephony/CallManager.java
index 09b7d05..7a026fa 100644
--- a/telephony/java/com/android/internal/telephony/CallManager.java
+++ b/telephony/java/com/android/internal/telephony/CallManager.java
@@ -1468,13 +1468,27 @@
*
*/
public Call getActiveFgCall() {
- for (Call call : mForegroundCalls) {
- if (call.getState() != Call.State.IDLE) {
+ Call call = getFirstNonIdleCall(mForegroundCalls);
+ if (call == null) {
+ call = (mDefaultPhone == null)
+ ? null
+ : mDefaultPhone.getForegroundCall();
+ }
+ return call;
+ }
+
+ // Returns the first call that is not in IDLE state. If both active calls
+ // and disconnecting/disconnected calls exist, return the first active call.
+ private Call getFirstNonIdleCall(List<Call> calls) {
+ Call result = null;
+ for (Call call : calls) {
+ if (!call.isIdle()) {
return call;
+ } else if (call.getState() != Call.State.IDLE) {
+ if (result == null) result = call;
}
}
- return (mDefaultPhone == null) ?
- null : mDefaultPhone.getForegroundCall();
+ return result;
}
/**
@@ -1491,13 +1505,13 @@
* Complete background calls list can be get by getBackgroundCalls()
*/
public Call getFirstActiveBgCall() {
- for (Call call : mBackgroundCalls) {
- if (call.getState() != Call.State.IDLE) {
- return call;
- }
+ Call call = getFirstNonIdleCall(mBackgroundCalls);
+ if (call == null) {
+ call = (mDefaultPhone == null)
+ ? null
+ : mDefaultPhone.getBackgroundCall();
}
- return (mDefaultPhone == null) ?
- null : mDefaultPhone.getBackgroundCall();
+ return call;
}
/**
@@ -1514,13 +1528,13 @@
* Complete ringing calls list can be get by getRingingCalls()
*/
public Call getFirstActiveRingingCall() {
- for (Call call : mRingingCalls) {
- if (!call.isIdle()) {
- return call;
- }
+ Call call = getFirstNonIdleCall(mRingingCalls);
+ if (call == null) {
+ call = (mDefaultPhone == null)
+ ? null
+ : mDefaultPhone.getRingingCall();
}
- return (mDefaultPhone == null) ?
- null : mDefaultPhone.getRingingCall();
+ return call;
}
/**
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhone.java b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
index 6ed9295..878d30c 100755
--- a/telephony/java/com/android/internal/telephony/sip/SipPhone.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
@@ -810,7 +810,10 @@
} catch (SipException e) {
throw new CallStateException("hangup(): " + e);
} finally {
- mAdapter.onCallEnded(DisconnectCause.LOCAL);
+ mAdapter.onCallEnded(((mState == Call.State.INCOMING)
+ || (mState == Call.State.WAITING))
+ ? DisconnectCause.INCOMING_REJECTED
+ : DisconnectCause.LOCAL);
}
}
}
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/GradientsActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/GradientsActivity.java
index 769bfdd..8fa626b 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/GradientsActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/GradientsActivity.java
@@ -18,11 +18,16 @@
import android.app.Activity;
import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
+import android.graphics.RadialGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Shader;
+import android.graphics.SweepGradient;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
@@ -36,8 +41,13 @@
super.onCreate(savedInstanceState);
final FrameLayout layout = new FrameLayout(this);
+
final ShadersView shadersView = new ShadersView(this);
final GradientView gradientView = new GradientView(this);
+ final RadialGradientView radialGradientView = new RadialGradientView(this);
+ final SweepGradientView sweepGradientView = new SweepGradientView(this);
+ final BitmapView bitmapView = new BitmapView(this);
+
final SeekBar rotateView = new SeekBar(this);
rotateView.setMax(360);
rotateView.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@@ -51,13 +61,29 @@
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- gradientView.setRotationY((float)progress);
+ gradientView.setRotationY((float) progress);
+ radialGradientView.setRotationX((float) progress);
+ sweepGradientView.setRotationY((float) progress);
+ bitmapView.setRotationX((float) progress);
}
});
layout.addView(shadersView);
layout.addView(gradientView, new FrameLayout.LayoutParams(
200, 200, Gravity.CENTER));
+
+ FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(200, 200, Gravity.CENTER);
+ lp.setMargins(220, 0, 0, 0);
+ layout.addView(radialGradientView, lp);
+
+ lp = new FrameLayout.LayoutParams(200, 200, Gravity.CENTER);
+ lp.setMargins(440, 0, 0, 0);
+ layout.addView(sweepGradientView, lp);
+
+ lp = new FrameLayout.LayoutParams(200, 200, Gravity.CENTER);
+ lp.setMargins(220, -220, 0, 0);
+ layout.addView(bitmapView, lp);
+
layout.addView(rotateView, new FrameLayout.LayoutParams(
300, FrameLayout.LayoutParams.WRAP_CONTENT,
Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM));
@@ -65,6 +91,32 @@
setContentView(layout);
}
+ static class BitmapView extends View {
+ private final Paint mPaint;
+
+ BitmapView(Context c) {
+ super(c);
+
+ Bitmap texture = BitmapFactory.decodeResource(c.getResources(), R.drawable.sunset1);
+ BitmapShader shader = new BitmapShader(texture, Shader.TileMode.REPEAT,
+ Shader.TileMode.REPEAT);
+ mPaint = new Paint();
+ mPaint.setShader(shader);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ setMeasuredDimension(200, 200);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ canvas.drawRect(0.0f, 0.0f, getWidth(), getHeight(), mPaint);
+ }
+ }
+
static class GradientView extends View {
private final Paint mPaint;
@@ -90,6 +142,55 @@
}
}
+ static class RadialGradientView extends View {
+ private final Paint mPaint;
+
+ RadialGradientView(Context c) {
+ super(c);
+
+ RadialGradient gradient = new RadialGradient(0.0f, 0.0f, 100.0f, 0xff000000, 0xffffffff,
+ Shader.TileMode.MIRROR);
+ mPaint = new Paint();
+ mPaint.setShader(gradient);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ setMeasuredDimension(200, 200);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ canvas.drawRect(0.0f, 0.0f, getWidth(), getHeight(), mPaint);
+ }
+ }
+
+ static class SweepGradientView extends View {
+ private final Paint mPaint;
+
+ SweepGradientView(Context c) {
+ super(c);
+
+ SweepGradient gradient = new SweepGradient(100.0f, 100.0f, 0xff000000, 0xffffffff);
+ mPaint = new Paint();
+ mPaint.setShader(gradient);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ setMeasuredDimension(200, 200);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ canvas.drawRect(0.0f, 0.0f, getWidth(), getHeight(), mPaint);
+ }
+ }
+
static class ShadersView extends View {
private final Paint mPaint;
private final float mDrawWidth;
diff --git a/tests/StatusBar/src/com/android/statusbartest/PowerTest.java b/tests/StatusBar/src/com/android/statusbartest/PowerTest.java
index f778cab..178fa92 100644
--- a/tests/StatusBar/src/com/android/statusbartest/PowerTest.java
+++ b/tests/StatusBar/src/com/android/statusbartest/PowerTest.java
@@ -49,6 +49,8 @@
int mPokeState = 0;
IBinder mPokeToken = new Binder();
Handler mHandler = new Handler();
+ PowerManager mPm;
+ PowerManager.WakeLock mProx;
@Override
protected String tag() {
@@ -58,10 +60,27 @@
@Override
protected Test[] tests() {
mPowerManager = IPowerManager.Stub.asInterface(ServiceManager.getService("power"));
+ mPm = (PowerManager)getSystemService("power");
+ mProx = mPm.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, "PowerTest-prox");
return mTests;
}
private Test[] mTests = new Test[] {
+ new Test("Enable proximity") {
+ public void run() {
+ mProx.acquire();
+ }
+ },
+ new Test("Disable proximity") {
+ public void run() {
+ mProx.release();
+ }
+ },
+ new Test("Disable proximity (WAIT_FOR_PROXIMITY_NEGATIVE)") {
+ public void run() {
+ mProx.release(PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE);
+ }
+ },
new Test("Cheek events don't poke") {
public void run() {
mPokeState |= LocalPowerManager.POKE_LOCK_IGNORE_CHEEK_EVENTS;
@@ -72,6 +91,7 @@
}
}
},
+
new Test("Cheek events poke") {
public void run() {
mPokeState &= ~LocalPowerManager.POKE_LOCK_IGNORE_CHEEK_EVENTS;