Merge "fix the build. more string disambiguaiton."
diff --git a/api/current.xml b/api/current.xml
index 99c62a8..63215a0 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -245987,7 +245987,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="t" type="T">
+<parameter name="arg0" type="T">
</parameter>
</method>
</interface>
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index f55b746..f0758fd 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -59,6 +59,7 @@
static bool gPreferSoftwareCodec;
static bool gPlaybackAudio;
static bool gWriteMP4;
+static bool gDisplayHistogram;
static String8 gWriteMP4Filename;
static int64_t getNowUs() {
@@ -68,6 +69,44 @@
return (int64_t)tv.tv_usec + tv.tv_sec * 1000000ll;
}
+static int CompareIncreasing(const int64_t *a, const int64_t *b) {
+ return (*a) < (*b) ? -1 : (*a) > (*b) ? 1 : 0;
+}
+
+static void displayDecodeHistogram(Vector<int64_t> *decodeTimesUs) {
+ printf("decode times:\n");
+
+ decodeTimesUs->sort(CompareIncreasing);
+
+ size_t n = decodeTimesUs->size();
+ int64_t minUs = decodeTimesUs->itemAt(0);
+ int64_t maxUs = decodeTimesUs->itemAt(n - 1);
+
+ printf("min decode time %lld us (%.2f secs)\n", minUs, minUs / 1E6);
+ printf("max decode time %lld us (%.2f secs)\n", maxUs, maxUs / 1E6);
+
+ size_t counts[100];
+ for (size_t i = 0; i < 100; ++i) {
+ counts[i] = 0;
+ }
+
+ for (size_t i = 0; i < n; ++i) {
+ int64_t x = decodeTimesUs->itemAt(i);
+
+ size_t slot = ((x - minUs) * 100) / (maxUs - minUs);
+ if (slot == 100) { slot = 99; }
+
+ ++counts[slot];
+ }
+
+ for (size_t i = 0; i < 100; ++i) {
+ int64_t slotUs = minUs + (i * (maxUs - minUs) / 100);
+
+ double fps = 1E6 / slotUs;
+ printf("[%.2f fps]: %d\n", fps, counts[i]);
+ }
+}
+
static void playSource(OMXClient *client, sp<MediaSource> &source) {
sp<MetaData> meta = source->getFormat();
@@ -201,6 +240,8 @@
int64_t sumDecodeUs = 0;
int64_t totalBytes = 0;
+ Vector<int64_t> decodeTimesUs;
+
while (numIterationsLeft-- > 0) {
long numFrames = 0;
@@ -224,9 +265,17 @@
break;
}
- if (buffer->range_length() > 0 && (n++ % 16) == 0) {
- printf(".");
- fflush(stdout);
+ if (buffer->range_length() > 0) {
+ if (gDisplayHistogram && n > 0) {
+ // Ignore the first time since it includes some setup
+ // cost.
+ decodeTimesUs.push(delayDecodeUs);
+ }
+
+ if ((n++ % 16) == 0) {
+ printf(".");
+ fflush(stdout);
+ }
}
sumDecodeUs += delayDecodeUs;
@@ -266,6 +315,10 @@
(double)sumDecodeUs / n);
printf("decoded a total of %d frame(s).\n", n);
+
+ if (gDisplayHistogram) {
+ displayDecodeHistogram(&decodeTimesUs);
+ }
} else if (!strncasecmp("audio/", mime, 6)) {
// Frame count makes less sense for audio, as the output buffer
// sizes may be different across decoders.
@@ -466,6 +519,8 @@
fprintf(stderr, " -o playback audio\n");
fprintf(stderr, " -w(rite) filename (write to .mp4 file)\n");
fprintf(stderr, " -k seek test\n");
+ fprintf(stderr, " -x display a histogram of decoding times/fps "
+ "(video only)\n");
}
int main(int argc, char **argv) {
@@ -482,12 +537,13 @@
gPreferSoftwareCodec = false;
gPlaybackAudio = false;
gWriteMP4 = false;
+ gDisplayHistogram = false;
sp<ALooper> looper;
sp<ARTSPController> rtspController;
int res;
- while ((res = getopt(argc, argv, "han:lm:b:ptsow:k")) >= 0) {
+ while ((res = getopt(argc, argv, "han:lm:b:ptsow:kx")) >= 0) {
switch (res) {
case 'a':
{
@@ -560,6 +616,12 @@
break;
}
+ case 'x':
+ {
+ gDisplayHistogram = true;
+ break;
+ }
+
case '?':
case 'h':
default:
diff --git a/core/java/android/net/SSLCertificateSocketFactory.java b/core/java/android/net/SSLCertificateSocketFactory.java
index b8a1113..f8f8a29 100644
--- a/core/java/android/net/SSLCertificateSocketFactory.java
+++ b/core/java/android/net/SSLCertificateSocketFactory.java
@@ -99,6 +99,7 @@
private final boolean mSecure;
/** @deprecated Use {@link #getDefault(int)} instead. */
+ @Deprecated
public SSLCertificateSocketFactory(int handshakeTimeoutMillis) {
this(handshakeTimeoutMillis, null, true);
}
diff --git a/core/java/android/net/http/CertificateChainValidator.java b/core/java/android/net/http/CertificateChainValidator.java
index 363a311..92be373 100644
--- a/core/java/android/net/http/CertificateChainValidator.java
+++ b/core/java/android/net/http/CertificateChainValidator.java
@@ -102,14 +102,15 @@
}
}
- return verifyServerDomainAndCertificates((X509Certificate[]) peerCertificates, domain);
+ return verifyServerDomainAndCertificates((X509Certificate[]) peerCertificates, domain, "RSA");
}
/**
* Similar to doHandshakeAndValidateServerCertificates but exposed to JNI for use
* by Chromium HTTPS stack to validate the cert chain.
- * @param certChain The bytes for certificates in ASN.1 DER encoded certficates format.
+ * @param certChain The bytes for certificates in ASN.1 DER encoded certificates format.
* @param domain The full website hostname and domain
+ * @param authType The authentication type for the cert chain
* @return An SSL error object if there is an error and null otherwise
*/
public static SslError verifyServerCertificates(
@@ -126,18 +127,19 @@
serverCertificates[i] = new X509CertImpl(certChain[i]);
}
- return verifyServerDomainAndCertificates(serverCertificates, domain);
+ return verifyServerDomainAndCertificates(serverCertificates, domain, authType);
}
/**
* Common code of doHandshakeAndValidateServerCertificates and verifyServerCertificates.
- * Calls DomainNamevalidator to valide the domain, and TrustManager to valide the certs.
+ * Calls DomainNamevalidator to verify the domain, and TrustManager to verify the certs.
* @param chain the cert chain in X509 cert format.
* @param domain The full website hostname and domain
+ * @param authType The authentication type for the cert chain
* @return An SSL error object if there is an error and null otherwise
*/
private static SslError verifyServerDomainAndCertificates(
- X509Certificate[] chain, String domain)
+ X509Certificate[] chain, String domain, String authType)
throws IOException {
// check if the first certificate in the chain is for this site
X509Certificate currCertificate = chain[0];
@@ -153,7 +155,7 @@
}
try {
- SSLParametersImpl.getDefaultTrustManager().checkServerTrusted(chain, "RSA");
+ SSLParametersImpl.getDefaultTrustManager().checkServerTrusted(chain, authType);
return null; // No errors.
} catch (CertificateException e) {
if (HttpLog.LOGV) {
diff --git a/core/java/android/net/http/SslCertificate.java b/core/java/android/net/http/SslCertificate.java
index c29926c..30f25a2 100644
--- a/core/java/android/net/http/SslCertificate.java
+++ b/core/java/android/net/http/SslCertificate.java
@@ -112,6 +112,7 @@
* @param validNotAfter The not-after date from the certificate validity period in ISO 8601 format
* @deprecated Use {@link #SslCertificate(String, String, Date, Date)}
*/
+ @Deprecated
public SslCertificate(
String issuedTo, String issuedBy, String validNotBefore, String validNotAfter) {
this(issuedTo, issuedBy, parseDate(validNotBefore), parseDate(validNotAfter));
@@ -157,6 +158,7 @@
*
* @deprecated Use {@link #getValidNotBeforeDate()}
*/
+ @Deprecated
public String getValidNotBefore() {
return formatDate(mValidNotBefore);
}
@@ -175,6 +177,7 @@
*
* @deprecated Use {@link #getValidNotAfterDate()}
*/
+ @Deprecated
public String getValidNotAfter() {
return formatDate(mValidNotAfter);
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 1fe2c5a..ddfcb06 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2396,14 +2396,6 @@
"selected_input_method_subtype";
/**
- * Setting to record the history of input method subtype, holding the pair of ID of IME
- * and its last used subtype.
- * @hide
- */
- public static final String INPUT_METHODS_SUBTYPE_HISTORY =
- "input_methods_subtype_history";
-
- /**
* Whether the device has been provisioned (0 = false, 1 = true)
*/
public static final String DEVICE_PROVISIONED = "device_provisioned";
diff --git a/core/java/android/util/EventLogTags.java b/core/java/android/util/EventLogTags.java
index 5cf5332..8c18417 100644
--- a/core/java/android/util/EventLogTags.java
+++ b/core/java/android/util/EventLogTags.java
@@ -29,6 +29,7 @@
* @deprecated This class is no longer functional.
* Use {@link android.util.EventLog} instead.
*/
+@Deprecated
public class EventLogTags {
public static class Description {
public final int mTag;
diff --git a/core/tests/coretests/src/android/net/http/CookiesTest.java b/core/tests/coretests/src/android/net/http/CookiesTest.java
index c9eca03..e736bc9 100644
--- a/core/tests/coretests/src/android/net/http/CookiesTest.java
+++ b/core/tests/coretests/src/android/net/http/CookiesTest.java
@@ -19,15 +19,20 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URISyntaxException;
+import java.util.List;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
import java.util.logging.StreamHandler;
import junit.framework.TestCase;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
+import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.impl.client.DefaultHttpClient;
import tests.http.MockResponse;
import tests.http.MockWebServer;
+import tests.http.RecordedRequest;
public final class CookiesTest extends TestCase {
@@ -66,4 +71,38 @@
logger.removeHandler(handler);
}
}
+
+ /**
+ * Test that cookies aren't case-sensitive with respect to hostname.
+ * http://b/3167208
+ */
+ public void testCookiesWithNonMatchingCase() throws Exception {
+ // use a proxy so we can manipulate the origin server's host name
+ server = new MockWebServer();
+ server.enqueue(new MockResponse()
+ .addHeader("Set-Cookie: a=first; Domain=my.t-mobile.com")
+ .addHeader("Set-Cookie: b=second; Domain=.T-mobile.com")
+ .addHeader("Set-Cookie: c=third; Domain=.t-mobile.com")
+ .setBody("This response sets some cookies."));
+ server.enqueue(new MockResponse()
+ .setBody("This response gets those cookies back."));
+ server.play();
+
+ HttpClient client = new DefaultHttpClient();
+ client.getParams().setParameter(
+ ConnRoutePNames.DEFAULT_PROXY, new HttpHost("localhost", server.getPort()));
+
+ HttpResponse getCookies = client.execute(new HttpGet("http://my.t-mobile.com/"));
+ getCookies.getEntity().consumeContent();
+ server.takeRequest();
+
+ HttpResponse sendCookies = client.execute(new HttpGet("http://my.t-mobile.com/"));
+ sendCookies.getEntity().consumeContent();
+ RecordedRequest sendCookiesRequest = server.takeRequest();
+ assertContains(sendCookiesRequest.getHeaders(), "Cookie: a=first; b=second; c=third");
+ }
+
+ private void assertContains(List<String> headers, String header) {
+ assertTrue(headers.toString(), headers.contains(header));
+ }
}
diff --git a/docs/html/guide/topics/graphics/2d-graphics.jd b/docs/html/guide/topics/graphics/2d-graphics.jd
index e46dbb4..acb6f9f 100644
--- a/docs/html/guide/topics/graphics/2d-graphics.jd
+++ b/docs/html/guide/topics/graphics/2d-graphics.jd
@@ -257,9 +257,9 @@
<p>
The border is used to define the stretchable and static areas of
the image. You indicate a stretchable section by drawing one (or more) 1-pixel-wide
- black line(s) in the left and top part of the border. (You can have as
- many stretchable sections as you want.) The relative size of the stretchable
- sections stays the same, so the largest sections always remain the largest.
+ black line(s) in the left and top part of the border (the other border pixels should
+ be fully transparent or white). You can have as many stretchable sections as you want:
+ their relative size stays the same, so the largest sections always remain the largest.
</p>
<p>
You can also define an optional drawable section of the image (effectively,
diff --git a/docs/html/sdk/ndk/index.jd b/docs/html/sdk/ndk/index.jd
index 11e6642..0f36345 100644
--- a/docs/html/sdk/ndk/index.jd
+++ b/docs/html/sdk/ndk/index.jd
@@ -84,34 +84,56 @@
<dd>
<ul>
+
+ <li>A new toolchain (based on GCC 4.4.3), which generates better code, and can also now
+be used as a standalone cross-compiler, for people who want to build their stuff with
+<code>./configure && make</code>. See
+docs/STANDALONE-TOOLCHAIN.html for the details. The binaries for GCC 4.4.0 are still provided,
+but the 4.2.1 binaries were removed.</li>
+
+ <li>Support for prebuilt static and shared libraries (docs/PREBUILTS.html), module
+exports and imports to make sharing and reuse of third-party modules much easier
+(docs/IMPORT-MODULE.html explains why).</li>
+
+ <li>A C++ STL implementation (based on STLport) is now provided as a helper module. It
+can be used either as a static or shared library (details and usage exemple under
+sources/android/stlport/README). <strong>Note:</strong> For now, C++ Exceptions and RTTI are still
+not supported.</li>
+
+ <li>Improvements to the <code>cpufeatures</code> helper library to deal with buggy
+kernel that incorrectly report they run on an ARMv7 CPU (while the device really is an ARMv6). We
+recommend developers that use it to simply rebuild their applications to benefit from it, then
+upload to Market.</li>
+
<li>Adds support for native activities, which allows you to write completely native
applications.</li>
<li>Adds an EGL library that lets you create and manage OpenGL ES textures and
services.</li>
- <li>Provides an interface that lets you write a native text-to-speech engine.</li>
-
<li>Adds native support for the following:
<ul>
- <li>the input subsystem (such as the keyboard and touch screen)</li>
+ <li>Input subsystem (such as the keyboard and touch screen)</li>
- <li>the window and surface subsystem.</li>
+ <li>Window and surface subsystem</li>
- <li>audio APIs based on the OpenSL ES standard that support playback and recording
- as well as control over platform audio effects.</li>
+ <li>Audio APIs based on the OpenSL ES standard that support playback and recording
+ as well as control over platform audio effects</li>
- <li>event loop APIs to wait for things such as input and sensor events.</li>
+ <li>Event loop APIs to wait for things such as input and sensor events</li>
- <li>accessing assets packaged in an <code>.apk</code> file.</li>
+ <li>Access to assets packaged in the <code>.apk</code></li>
- <li>accessing sensor data (accelerometer, compass, gyroscope, etc).</li>
-
- <li>provides sample applications, <code>native-plasma</code> and
- <code>native-activity</code>, to demonstrate how to write a native activity.</li>
+ <li>Access to sensor data (accelerometer, compass, gyroscope, etc.)</li>
</ul>
</li>
+
+ <li>New sample applications, <code>native-plasma</code> and
+ <code>native-activity</code>, to demonstrate how to write a native activity.</li>
+
+ <li>Plus many bugfixes and other small improvements; see docs/CHANGES.html for a more
+detailed list of changes.</li>
</ul>
</dd>
</dl>
diff --git a/include/media/stagefright/MPEG4Writer.h b/include/media/stagefright/MPEG4Writer.h
index bb469e5..7bf07eb 100644
--- a/include/media/stagefright/MPEG4Writer.h
+++ b/include/media/stagefright/MPEG4Writer.h
@@ -154,6 +154,7 @@
bool exceedsFileDurationLimit();
bool isFileStreamable() const;
void trackProgressStatus(const Track* track, int64_t timeUs, status_t err = OK);
+ void writeCompositionMatrix(int32_t degrees);
MPEG4Writer(const MPEG4Writer &);
MPEG4Writer &operator=(const MPEG4Writer &);
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 6a25dc5..9da5f01 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -345,6 +345,17 @@
return OK;
}
+// Always rotate clockwise, and only support 0, 90, 180 and 270 for now.
+status_t StagefrightRecorder::setParamVideoRotation(int32_t degrees) {
+ LOGV("setParamVideoRotation: %d", degrees);
+ if (degrees < 0 || degrees % 90 != 0) {
+ LOGE("Unsupported video rotation angle: %d", degrees);
+ return BAD_VALUE;
+ }
+ mRotationDegrees = degrees % 360;
+ return OK;
+}
+
status_t StagefrightRecorder::setParamMaxFileDurationUs(int64_t timeUs) {
LOGV("setParamMaxFileDurationUs: %lld us", timeUs);
if (timeUs <= 0) {
@@ -599,6 +610,11 @@
if (safe_strtoi32(value.string(), &video_bitrate)) {
return setParamVideoEncodingBitRate(video_bitrate);
}
+ } else if (key == "video-param-rotation-angle-degrees") {
+ int32_t degrees;
+ if (safe_strtoi32(value.string(), °rees)) {
+ return setParamVideoRotation(degrees);
+ }
} else if (key == "video-param-i-frames-interval") {
int32_t seconds;
if (safe_strtoi32(value.string(), &seconds)) {
@@ -1255,6 +1271,9 @@
if (mTrackEveryTimeDurationUs > 0) {
(*meta)->setInt64(kKeyTrackTimeStatus, mTrackEveryTimeDurationUs);
}
+ if (mRotationDegrees != 0) {
+ (*meta)->setInt32(kKeyRotation, mRotationDegrees);
+ }
}
status_t StagefrightRecorder::startMPEG4Recording() {
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
index d11d7e0..36a15a8 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -93,6 +93,7 @@
int64_t mMaxFileSizeBytes;
int64_t mMaxFileDurationUs;
int64_t mTrackEveryTimeDurationUs;
+ int32_t mRotationDegrees; // Clockwise
bool mCaptureTimeLapse;
int64_t mTimeBetweenTimeLapseFrameCaptureUs;
@@ -146,6 +147,7 @@
status_t setParamVideoEncoderLevel(int32_t level);
status_t setParamVideoCameraId(int32_t cameraId);
status_t setParamVideoTimeScale(int32_t timeScale);
+ status_t setParamVideoRotation(int32_t degrees);
status_t setParamTrackTimeStatus(int64_t timeDurationUs);
status_t setParamInterleaveDuration(int32_t durationUs);
status_t setParam64BitFileOffset(bool use64BitFileOffset);
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index b3ed845..17a40b00 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -202,6 +202,7 @@
// Simple validation on the codec specific data
status_t checkCodecSpecificData() const;
+ int32_t mRotation;
void updateTrackSizeEstimate();
void addOneStscTableEntry(size_t chunkId, size_t sampleId);
@@ -520,6 +521,59 @@
LOGD("Writer thread stopped");
}
+/*
+ * MP4 file standard defines a composition matrix:
+ * | a b u |
+ * | c d v |
+ * | x y w |
+ *
+ * the element in the matrix is stored in the following
+ * order: {a, b, u, c, d, v, x, y, w},
+ * where a, b, c, d, x, and y is in 16.16 format, while
+ * u, v and w is in 2.30 format.
+ */
+void MPEG4Writer::writeCompositionMatrix(int degrees) {
+ LOGV("writeCompositionMatrix");
+ uint32_t a = 0x00010000;
+ uint32_t b = 0;
+ uint32_t c = 0;
+ uint32_t d = 0x00010000;
+ switch (degrees) {
+ case 0:
+ break;
+ case 90:
+ a = 0;
+ b = 0x00010000;
+ c = 0xFFFF0000;
+ d = 0;
+ break;
+ case 180:
+ a = 0xFFFF0000;
+ d = 0xFFFF0000;
+ break;
+ case 270:
+ a = 0;
+ b = 0xFFFF0000;
+ c = 0x00010000;
+ d = 0;
+ break;
+ default:
+ CHECK(!"Should never reach this unknown rotation");
+ break;
+ }
+
+ writeInt32(a); // a
+ writeInt32(b); // b
+ writeInt32(0); // u
+ writeInt32(c); // c
+ writeInt32(d); // d
+ writeInt32(0); // v
+ writeInt32(0); // x
+ writeInt32(0); // y
+ writeInt32(0x40000000); // w
+}
+
+
status_t MPEG4Writer::stop() {
if (mFile == NULL) {
return OK;
@@ -585,15 +639,7 @@
writeInt16(0); // reserved
writeInt32(0); // reserved
writeInt32(0); // reserved
- writeInt32(0x10000); // matrix
- writeInt32(0);
- writeInt32(0);
- writeInt32(0);
- writeInt32(0x10000);
- writeInt32(0);
- writeInt32(0);
- writeInt32(0);
- writeInt32(0x40000000);
+ writeCompositionMatrix(0); // matrix
writeInt32(0); // predefined
writeInt32(0); // predefined
writeInt32(0); // predefined
@@ -886,7 +932,8 @@
mCodecSpecificData(NULL),
mCodecSpecificDataSize(0),
mGotAllCodecSpecificData(false),
- mReachedEOS(false) {
+ mReachedEOS(false),
+ mRotation(0) {
getCodecSpecificDataFromInputFormatIfPossible();
const char *mime;
@@ -1179,6 +1226,11 @@
startTimeUs = 0;
}
+ int32_t rotationDegrees;
+ if (!mIsAudio && params && params->findInt32(kKeyRotation, &rotationDegrees)) {
+ mRotation = rotationDegrees;
+ }
+
mIsRealTimeRecording = true;
{
int32_t isNotRealTime;
@@ -2075,15 +2127,7 @@
mOwner->writeInt16(mIsAudio ? 0x100 : 0); // volume
mOwner->writeInt16(0); // reserved
- mOwner->writeInt32(0x10000); // matrix
- mOwner->writeInt32(0);
- mOwner->writeInt32(0);
- mOwner->writeInt32(0);
- mOwner->writeInt32(0x10000);
- mOwner->writeInt32(0);
- mOwner->writeInt32(0);
- mOwner->writeInt32(0);
- mOwner->writeInt32(0x40000000);
+ mOwner->writeCompositionMatrix(mRotation); // matrix
if (mIsAudio) {
mOwner->writeInt32(0);
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index da5f204..d035eb5 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -116,7 +116,6 @@
static final long TIME_TO_RECONNECT = 10*1000;
private static final int NOT_A_SUBTYPE_ID = -1;
- private static final String NOT_A_SUBTYPE_ID_STR = String.valueOf(NOT_A_SUBTYPE_ID);
// If IME doesn't support the system locale, the default subtype will be the first defined one.
private static final int DEFAULT_SUBTYPE_ID = 0;
@@ -367,7 +366,9 @@
if (!doit) {
return true;
}
- resetSelectedInputMethodAndSubtypeLocked("");
+ Settings.Secure.putString(mContext.getContentResolver(),
+ Settings.Secure.DEFAULT_INPUT_METHOD, "");
+ resetSelectedInputMethodSubtype();
chooseNewDefaultIMELocked();
return true;
}
@@ -424,7 +425,9 @@
changed = true;
curIm = null;
Slog.i(TAG, "Unsetting current input method");
- resetSelectedInputMethodAndSubtypeLocked("");
+ Settings.Secure.putString(mContext.getContentResolver(),
+ Settings.Secure.DEFAULT_INPUT_METHOD, "");
+ resetSelectedInputMethodSubtype();
}
}
}
@@ -507,7 +510,9 @@
Slog.i(TAG, "No default found, using " + defIm.getId());
}
if (defIm != null) {
- setSelectSubtypeLocked(defIm, NOT_A_SUBTYPE_ID);
+ Settings.Secure.putString(mContext.getContentResolver(),
+ Settings.Secure.DEFAULT_INPUT_METHOD, defIm.getId());
+ putSelectedInputMethodSubtype(defIm, NOT_A_SUBTYPE_ID);
}
}
@@ -989,7 +994,7 @@
synchronized (mMethodMap) {
if (mCurMethod != null) {
try {
- setSelectSubtypeLocked(info, subtypeId);
+ putSelectedInputMethodSubtype(info, subtypeId);
if (mInputShown) {
// If mInputShown is false, there is no IME button on the
// system bar.
@@ -1009,13 +1014,13 @@
final long ident = Binder.clearCallingIdentity();
try {
+ mCurMethodId = id;
// Set a subtype to this input method.
// subtypeId the name of a subtype which will be set.
- setSelectedInputMethodAndSubtypeLocked(info, subtypeId);
- // mCurMethodId should be updated after setSelectedInputMethodAndSubtypeLocked()
- // because mCurMethodId is stored as a history in
- // setSelectedInputMethodAndSubtypeLocked().
- mCurMethodId = id;
+ putSelectedInputMethodSubtype(info, subtypeId);
+
+ Settings.Secure.putString(mContext.getContentResolver(),
+ Settings.Secure.DEFAULT_INPUT_METHOD, id);
if (ActivityManagerNative.isSystemReady()) {
Intent intent = new Intent(Intent.ACTION_INPUT_METHOD_CHANGED);
@@ -1482,7 +1487,9 @@
}
}
InputMethodInfo imi = enabled.get(i);
- resetSelectedInputMethodAndSubtypeLocked(imi.getId());
+ Settings.Secure.putString(mContext.getContentResolver(),
+ Settings.Secure.DEFAULT_INPUT_METHOD, imi.getId());
+ putSelectedInputMethodSubtype(imi, NOT_A_SUBTYPE_ID);
return true;
}
@@ -1786,8 +1793,11 @@
String selId = Settings.Secure.getString(mContext.getContentResolver(),
Settings.Secure.DEFAULT_INPUT_METHOD);
if (id.equals(selId)) {
- resetSelectedInputMethodAndSubtypeLocked(enabledInputMethodsList.size() > 0
- ? enabledInputMethodsList.get(0).first : "");
+ Settings.Secure.putString(
+ mContext.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD,
+ enabledInputMethodsList.size() > 0
+ ? enabledInputMethodsList.get(0).first : "");
+ resetSelectedInputMethodSubtype();
}
// Previous state was enabled.
return true;
@@ -1799,54 +1809,22 @@
}
}
- private void saveCurrentInputMethodAndSubtypeToHistory() {
- String subtypeId = NOT_A_SUBTYPE_ID_STR;
- if (mCurrentSubtype != null) {
- subtypeId = String.valueOf(mCurrentSubtype.hashCode());
- }
- mSettings.addSubtypeToHistory(mCurMethodId, subtypeId);
+ private void resetSelectedInputMethodSubtype() {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE, NOT_A_SUBTYPE_ID);
}
- private void setSelectSubtypeLocked(InputMethodInfo imi, int subtypeId) {
- saveCurrentInputMethodAndSubtypeToHistory();
- if (imi == null || subtypeId < 0) {
- mSettings.putSelectedSubtype(NOT_A_SUBTYPE_ID);
- mCurrentSubtype = null;
+ private void putSelectedInputMethodSubtype(InputMethodInfo imi, int subtypeId) {
+ final ArrayList<InputMethodSubtype> subtypes = imi.getSubtypes();
+ if (subtypeId >= 0 && subtypeId < subtypes.size()) {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE,
+ subtypes.get(subtypeId).hashCode());
+ mCurrentSubtype = subtypes.get(subtypeId);
} else {
- final ArrayList<InputMethodSubtype> subtypes = imi.getSubtypes();
- if (subtypeId < subtypes.size()) {
- mSettings.putSelectedSubtype(subtypes.get(subtypeId).hashCode());
- mCurrentSubtype = subtypes.get(subtypeId);
- } else {
- mSettings.putSelectedSubtype(NOT_A_SUBTYPE_ID);
- mCurrentSubtype = null;
- }
+ resetSelectedInputMethodSubtype();
+ mCurrentSubtype = null;
}
-
- }
-
- private void setSelectedInputMethodAndSubtypeLocked(InputMethodInfo imi, int subtypeId) {
- setSelectSubtypeLocked(imi, subtypeId);
- mSettings.putSelectedInputMethod(imi.getId());
- }
-
- private void resetSelectedInputMethodAndSubtypeLocked(String newDefaultIme) {
- InputMethodInfo imi = mMethodMap.get(newDefaultIme);
- int lastSubtypeId = NOT_A_SUBTYPE_ID;
- // newDefaultIme is empty when there is no candidate for the selected IME.
- if (imi != null && !TextUtils.isEmpty(newDefaultIme)) {
- String subtypeHashCode = mSettings.getLastSubtypeForInputMethodLocked(newDefaultIme);
- if (subtypeHashCode != null) {
- try {
- lastSubtypeId = getSubtypeIdFromHashCode(
- imi, Integer.valueOf(subtypeHashCode));
- } catch (NumberFormatException e) {
- Slog.w(TAG, "HashCode for subtype looks broken: " + subtypeHashCode, e);
- }
- }
- }
- setSelectSubtypeLocked(imi, lastSubtypeId);
- mSettings.putSelectedInputMethod(newDefaultIme);
}
private int getSelectedInputMethodSubtypeId(String id) {
@@ -1854,6 +1832,7 @@
if (imi == null) {
return NOT_A_SUBTYPE_ID;
}
+ ArrayList<InputMethodSubtype> subtypes = imi.getSubtypes();
int subtypeId;
try {
subtypeId = Settings.Secure.getInt(mContext.getContentResolver(),
@@ -1861,14 +1840,9 @@
} catch (SettingNotFoundException e) {
return NOT_A_SUBTYPE_ID;
}
- return getSubtypeIdFromHashCode(imi, subtypeId);
- }
-
- private int getSubtypeIdFromHashCode(InputMethodInfo imi, int subtypeHashCode) {
- ArrayList<InputMethodSubtype> subtypes = imi.getSubtypes();
for (int i = 0; i < subtypes.size(); ++i) {
InputMethodSubtype ims = subtypes.get(i);
- if (subtypeHashCode == ims.hashCode()) {
+ if (subtypeId == ims.hashCode()) {
return i;
}
}
@@ -1948,10 +1922,10 @@
// example: ("ime0;subtype0;subtype1;subtype2:ime1:ime2;subtype0")
private static final char INPUT_METHOD_SEPARATER = ':';
private static final char INPUT_METHOD_SUBTYPE_SEPARATER = ';';
- private final TextUtils.SimpleStringSplitter mInputMethodSplitter =
+ private final TextUtils.SimpleStringSplitter mStringColonSplitter =
new TextUtils.SimpleStringSplitter(INPUT_METHOD_SEPARATER);
- private final TextUtils.SimpleStringSplitter mSubtypeSplitter =
+ private final TextUtils.SimpleStringSplitter mStringSemiColonSplitter =
new TextUtils.SimpleStringSplitter(INPUT_METHOD_SUBTYPE_SEPARATER);
private final ContentResolver mResolver;
@@ -2014,16 +1988,16 @@
if (TextUtils.isEmpty(enabledInputMethodsStr)) {
return imsList;
}
- mInputMethodSplitter.setString(enabledInputMethodsStr);
- while (mInputMethodSplitter.hasNext()) {
- String nextImsStr = mInputMethodSplitter.next();
- mSubtypeSplitter.setString(nextImsStr);
- if (mSubtypeSplitter.hasNext()) {
+ mStringColonSplitter.setString(enabledInputMethodsStr);
+ while (mStringColonSplitter.hasNext()) {
+ String nextImsStr = mStringColonSplitter.next();
+ mStringSemiColonSplitter.setString(nextImsStr);
+ if (mStringSemiColonSplitter.hasNext()) {
ArrayList<String> subtypeHashes = new ArrayList<String>();
// The first element is ime id.
- String imeId = mSubtypeSplitter.next();
- while (mSubtypeSplitter.hasNext()) {
- subtypeHashes.add(mSubtypeSplitter.next());
+ String imeId = mStringSemiColonSplitter.next();
+ while (mStringSemiColonSplitter.hasNext()) {
+ subtypeHashes.add(mStringSemiColonSplitter.next());
}
imsList.add(new Pair<String, ArrayList<String>>(imeId, subtypeHashes));
}
@@ -2109,161 +2083,8 @@
private String getEnabledInputMethodsStr() {
mEnabledInputMethodsStrCache = Settings.Secure.getString(
mResolver, Settings.Secure.ENABLED_INPUT_METHODS);
- if (DEBUG) {
- Slog.d(TAG, "getEnabledInputMethodsStr: " + mEnabledInputMethodsStrCache);
- }
return mEnabledInputMethodsStrCache;
}
-
- private void saveSubtypeHistory(
- List<Pair<String, String>> savedImes, String newImeId, String newSubtypeId) {
- StringBuilder builder = new StringBuilder();
- boolean isImeAdded = false;
- if (!TextUtils.isEmpty(newImeId) && !TextUtils.isEmpty(newSubtypeId)) {
- builder.append(newImeId).append(INPUT_METHOD_SUBTYPE_SEPARATER).append(
- newSubtypeId);
- isImeAdded = true;
- }
- for (Pair<String, String> ime: savedImes) {
- String imeId = ime.first;
- String subtypeId = ime.second;
- if (TextUtils.isEmpty(subtypeId)) {
- subtypeId = NOT_A_SUBTYPE_ID_STR;
- }
- if (isImeAdded) {
- builder.append(INPUT_METHOD_SEPARATER);
- } else {
- isImeAdded = true;
- }
- builder.append(imeId).append(INPUT_METHOD_SUBTYPE_SEPARATER).append(
- subtypeId);
- }
- // Remove the last INPUT_METHOD_SEPARATER
- putSubtypeHistoryStr(builder.toString());
- }
-
- public void addSubtypeToHistory(String imeId, String subtypeId) {
- List<Pair<String, String>> subtypeHistory = loadInputMethodAndSubtypeHistoryLocked();
- for (Pair<String, String> ime: subtypeHistory) {
- if (ime.first.equals(imeId)) {
- if (DEBUG) {
- Slog.v(TAG, "Subtype found in the history: " + imeId
- + ime.second);
- }
- // We should break here
- subtypeHistory.remove(ime);
- break;
- }
- }
- saveSubtypeHistory(subtypeHistory, imeId, subtypeId);
- }
-
- private void putSubtypeHistoryStr(String str) {
- if (DEBUG) {
- Slog.d(TAG, "putSubtypeHistoryStr: " + str);
- }
- Settings.Secure.putString(
- mResolver, Settings.Secure.INPUT_METHODS_SUBTYPE_HISTORY, str);
- }
-
- public Pair<String, String> getLastInputMethodAndSubtypeLocked() {
- // Gets the first one from the history
- return getLastSubtypeForInputMethodLockedInternal(null);
- }
-
- public String getLastSubtypeForInputMethodLocked(String imeId) {
- Pair<String, String> ime = getLastSubtypeForInputMethodLockedInternal(imeId);
- if (ime != null) {
- return ime.second;
- } else {
- return null;
- }
- }
-
- private Pair<String, String> getLastSubtypeForInputMethodLockedInternal(String imeId) {
- List<Pair<String, ArrayList<String>>> enabledImes =
- getEnabledInputMethodsAndSubtypeListLocked();
- List<Pair<String, String>> subtypeHistory = loadInputMethodAndSubtypeHistoryLocked();
- for (Pair<String, String> imeAndSubtype: subtypeHistory) {
- final String imeInTheHistory = imeAndSubtype.first;
- // If imeId is empty, returns the first IME and subtype in the history
- if (TextUtils.isEmpty(imeId) || imeInTheHistory.equals(imeId)) {
- final String subtypeInTheHistory = imeAndSubtype.second;
- final String subtypeHashCode = getEnabledSubtypeForInputMethodAndSubtypeLocked(
- enabledImes, imeInTheHistory, subtypeInTheHistory);
- if (!TextUtils.isEmpty(subtypeHashCode)) {
- if (DEBUG) {
- Slog.d(TAG, "Enabled subtype found in the history:" + subtypeHashCode);
- }
- return new Pair<String, String>(imeInTheHistory, subtypeHashCode);
- }
- }
- }
- if (DEBUG) {
- Slog.d(TAG, "No enabled IME found in the history");
- }
- return null;
- }
-
- private String getEnabledSubtypeForInputMethodAndSubtypeLocked(List<Pair<String,
- ArrayList<String>>> enabledImes, String imeId, String subtypeHashCode) {
- for (Pair<String, ArrayList<String>> enabledIme: enabledImes) {
- if (enabledIme.first.equals(imeId)) {
- for (String s: enabledIme.second) {
- if (s.equals(subtypeHashCode)) {
- // If both imeId and subtypeId are enabled, return subtypeId.
- return s;
- }
- }
- // If imeId was enabled but subtypeId was disabled.
- return NOT_A_SUBTYPE_ID_STR;
- }
- }
- // If both imeId and subtypeId are disabled, return null
- return null;
- }
-
- private List<Pair<String, String>> loadInputMethodAndSubtypeHistoryLocked() {
- ArrayList<Pair<String, String>> imsList = new ArrayList<Pair<String, String>>();
- final String subtypeHistoryStr = getSubtypeHistoryStr();
- if (TextUtils.isEmpty(subtypeHistoryStr)) {
- return imsList;
- }
- mInputMethodSplitter.setString(subtypeHistoryStr);
- while (mInputMethodSplitter.hasNext()) {
- String nextImsStr = mInputMethodSplitter.next();
- mSubtypeSplitter.setString(nextImsStr);
- if (mSubtypeSplitter.hasNext()) {
- String subtypeId = NOT_A_SUBTYPE_ID_STR;
- // The first element is ime id.
- String imeId = mSubtypeSplitter.next();
- while (mSubtypeSplitter.hasNext()) {
- subtypeId = mSubtypeSplitter.next();
- break;
- }
- imsList.add(new Pair<String, String>(imeId, subtypeId));
- }
- }
- return imsList;
- }
-
- private String getSubtypeHistoryStr() {
- if (DEBUG) {
- Slog.d(TAG, "getSubtypeHistoryStr: " + Settings.Secure.getString(
- mResolver, Settings.Secure.INPUT_METHODS_SUBTYPE_HISTORY));
- }
- return Settings.Secure.getString(
- mResolver, Settings.Secure.INPUT_METHODS_SUBTYPE_HISTORY);
- }
-
- public void putSelectedInputMethod(String imeId) {
- Settings.Secure.putString(mResolver, Settings.Secure.DEFAULT_INPUT_METHOD, imeId);
- }
-
- public void putSelectedSubtype(int subtypeId) {
- Settings.Secure.putInt(
- mResolver, Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE, subtypeId);
- }
}
// ----------------------------------------------------------------------
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/FileFilter.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/FileFilter.java
index ebdf9c2..6c33a21 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/FileFilter.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/FileFilter.java
@@ -240,13 +240,18 @@
/**
* Checks if the file is a test.
- * Currently we run .html and .xhtml tests.
+ * Currently we run .html, .xhtml and .php tests.
+ *
+ * @warning You MUST also call isTestDir() on the parent directory before
+ * assuming that a file is a test.
*
* @param testName
* @return if the file is a test
*/
public static boolean isTestFile(String testName) {
- return testName.endsWith(".html") || testName.endsWith(".xhtml");
+ return testName.endsWith(".html")
+ || testName.endsWith(".xhtml")
+ || testName.endsWith(".php");
}
/**