Merge "More work in progress on native events." into gingerbread
diff --git a/api/current.xml b/api/current.xml
index 41b0423..3acd21f 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -13112,72 +13112,6 @@
visibility="public"
>
</field>
-<field name="kraken_resource_pad80"
- type="int"
- transient="false"
- volatile="false"
- value="17301681"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="kraken_resource_pad81"
- type="int"
- transient="false"
- volatile="false"
- value="17301680"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="kraken_resource_pad82"
- type="int"
- transient="false"
- volatile="false"
- value="17301679"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="kraken_resource_pad83"
- type="int"
- transient="false"
- volatile="false"
- value="17301678"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="kraken_resource_pad84"
- type="int"
- transient="false"
- volatile="false"
- value="17301677"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="kraken_resource_pad85"
- type="int"
- transient="false"
- volatile="false"
- value="17301676"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="kraken_resource_pad9"
type="int"
transient="false"
@@ -13244,6 +13178,39 @@
visibility="public"
>
</field>
+<field name="presence_audio_away"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="17301679"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="presence_audio_busy"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="17301680"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="presence_audio_online"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="17301681"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="presence_away"
type="int"
transient="false"
@@ -13299,6 +13266,39 @@
visibility="public"
>
</field>
+<field name="presence_video_away"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="17301676"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="presence_video_busy"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="17301677"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="presence_video_online"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="17301678"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="progress_horizontal"
type="int"
transient="false"
@@ -117454,17 +117454,6 @@
visibility="public"
>
</field>
-<field name="KRAKEN"
- type="int"
- transient="false"
- volatile="false"
- value="10000"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
</class>
<class name="Bundle"
extends="java.lang.Object"
diff --git a/common/Android.mk b/common/Android.mk
deleted file mode 100644
index 1f78840..0000000
--- a/common/Android.mk
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (C) 2009 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.
-
-LOCAL_PATH := $(call my-dir)
-
-# Note: the source code is in java/, not src/, because this code is also part of
-# the framework library, and build/core/pathmap.mk expects a java/ subdirectory.
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := android-common
-LOCAL_SDK_VERSION := current
-LOCAL_SRC_FILES := \
- $(call all-java-files-under, java) \
- $(call all-logtags-files-under, java)
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-# Include this library in the build server's output directory
-$(call dist-for-goals, droid, $(LOCAL_BUILT_MODULE):android-common.jar)
-
-# Build the test package
-include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/common/java/com/android/common/ArrayListCursor.java b/common/java/com/android/common/ArrayListCursor.java
deleted file mode 100644
index 9ad5c36..0000000
--- a/common/java/com/android/common/ArrayListCursor.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2006 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.common;
-
-import android.database.AbstractCursor;
-import android.database.CursorWindow;
-
-import java.lang.System;
-import java.util.ArrayList;
-
-/**
- * A convenience class that presents a two-dimensional ArrayList
- * as a Cursor.
- * @deprecated This is has been replaced by MatrixCursor.
-*/
-public class ArrayListCursor extends AbstractCursor {
- private String[] mColumnNames;
- private ArrayList<Object>[] mRows;
-
- @SuppressWarnings({"unchecked"})
- public ArrayListCursor(String[] columnNames, ArrayList<ArrayList> rows) {
- int colCount = columnNames.length;
- boolean foundID = false;
- // Add an _id column if not in columnNames
- for (int i = 0; i < colCount; ++i) {
- if (columnNames[i].compareToIgnoreCase("_id") == 0) {
- mColumnNames = columnNames;
- foundID = true;
- break;
- }
- }
-
- if (!foundID) {
- mColumnNames = new String[colCount + 1];
- System.arraycopy(columnNames, 0, mColumnNames, 0, columnNames.length);
- mColumnNames[colCount] = "_id";
- }
-
- int rowCount = rows.size();
- mRows = new ArrayList[rowCount];
-
- for (int i = 0; i < rowCount; ++i) {
- mRows[i] = rows.get(i);
- if (!foundID) {
- mRows[i].add(i);
- }
- }
- }
-
- @Override
- public void fillWindow(int position, CursorWindow window) {
- if (position < 0 || position > getCount()) {
- return;
- }
-
- window.acquireReference();
- try {
- int oldpos = mPos;
- mPos = position - 1;
- window.clear();
- window.setStartPosition(position);
- int columnNum = getColumnCount();
- window.setNumColumns(columnNum);
- while (moveToNext() && window.allocRow()) {
- for (int i = 0; i < columnNum; i++) {
- final Object data = mRows[mPos].get(i);
- if (data != null) {
- if (data instanceof byte[]) {
- byte[] field = (byte[]) data;
- if (!window.putBlob(field, mPos, i)) {
- window.freeLastRow();
- break;
- }
- } else {
- String field = data.toString();
- if (!window.putString(field, mPos, i)) {
- window.freeLastRow();
- break;
- }
- }
- } else {
- if (!window.putNull(mPos, i)) {
- window.freeLastRow();
- break;
- }
- }
- }
- }
-
- mPos = oldpos;
- } catch (IllegalStateException e){
- // simply ignore it
- } finally {
- window.releaseReference();
- }
- }
-
- @Override
- public int getCount() {
- return mRows.length;
- }
-
- @Override
- public String[] getColumnNames() {
- return mColumnNames;
- }
-
- @Override
- public byte[] getBlob(int columnIndex) {
- return (byte[]) mRows[mPos].get(columnIndex);
- }
-
- @Override
- public String getString(int columnIndex) {
- Object cell = mRows[mPos].get(columnIndex);
- return (cell == null) ? null : cell.toString();
- }
-
- @Override
- public short getShort(int columnIndex) {
- Number num = (Number) mRows[mPos].get(columnIndex);
- return num.shortValue();
- }
-
- @Override
- public int getInt(int columnIndex) {
- Number num = (Number) mRows[mPos].get(columnIndex);
- return num.intValue();
- }
-
- @Override
- public long getLong(int columnIndex) {
- Number num = (Number) mRows[mPos].get(columnIndex);
- return num.longValue();
- }
-
- @Override
- public float getFloat(int columnIndex) {
- Number num = (Number) mRows[mPos].get(columnIndex);
- return num.floatValue();
- }
-
- @Override
- public double getDouble(int columnIndex) {
- Number num = (Number) mRows[mPos].get(columnIndex);
- return num.doubleValue();
- }
-
- @Override
- public boolean isNull(int columnIndex) {
- return mRows[mPos].get(columnIndex) == null;
- }
-}
diff --git a/common/java/com/android/common/GoogleLogTags.logtags b/common/java/com/android/common/GoogleLogTags.logtags
deleted file mode 100644
index f848ddf..0000000
--- a/common/java/com/android/common/GoogleLogTags.logtags
+++ /dev/null
@@ -1,100 +0,0 @@
-# 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.
-
-option java_package com.android.common
-
-#####
-# This file contains definitions for event log (android.util.EventLog) tags
-# used by Google Mobile Services applications. These definitions are part of
-# the platform even when the Google applications are not.
-#
-# See system/core/logcat/event.logtags for a description of the file format.
-#
-# These event log tags must be assigned specific numbers (no "?") in the range
-# 200000-300000. If new tags are added, be aware that older platforms will be
-# missing the tag definitions, and may not be able to show them in their logs.
-
-#####
-# System Update (OTA)
-
-# System update status bits
-# [31- 9] Reserved for future use
-# [ 8- 7] package verified (0=not attempted, 1=succeeded, 2=failed)
-# [ 6] install approved
-# [ 5] download approved
-# [ 4- 0] status
-201001 system_update (status|1|5),(download_result|1|5),(bytes|2|2),(url|3)
-201002 system_update_user (action|3)
-
-#####
-# Android Market
-
-# @param changes Number of changes made to database in reconstruct
-202001 vending_reconstruct (changes|1)
-
-#####
-# Google Services Framework
-
-203001 sync_details (authority|3),(send|1|2),(recv|1|2),(details|3)
-
-203002 google_http_request (elapsed|2|3),(status|1),(appname|3),(reused|1)
-
-#####
-# Google Talk Service
-
-# This event is logged when GTalkService encounters important events
-204001 gtalkservice (eventType|1)
-# This event is logged for GTalk connection state changes. The status field is an int, but
-# it really contains 4 separate values, each taking up a byte
-# (eventType << 24) + (connection state << 16) + (connection error << 8) + network state
-204002 gtalk_connection (status|1)
-
-# This event is logged when GTalk connection is closed.
-# The status field is an int, but contains 2 different values, it's represented as
-#
-# (networkType << 8) + connection error
-#
-# the possible error values are
-#
-# no_error=0, no_network=1, connection_failed=2, unknown_host=3, auth_failed=4,
-# auth_expired=5, heart_beat_timeout=6, server_error=7, server_reject_rate_limiting=8, unknown=10
-#
-# duration is the connection duration.
-204003 gtalk_conn_close (status|1),(duration|1)
-
-# This event is logged for GTalk heartbeat resets
-# interval_and_nt contains both the heartbeat interval and the network type, It's represented as
-# (networkType << 16) + interval
-# interval is in seconds; network type can be 0 (mobile) or 1 (wifi); ip is the host ip addr.
-204004 gtalk_heartbeat_reset (interval_and_nt|1),(ip|3)
-
-# This event is logged when an Rmq v2 packet is sent or received.
-204005 c2dm (packet_type|1),(persistent_id|3),(stream_id|1),(last_stream_id|1)
-
-#####
-# Google Login Service and Setup Wizard
-
-# This event is for when communicating to the server times out during account setup
-205001 setup_server_timeout
-205002 setup_required_captcha (action|3)
-205003 setup_io_error (status|3)
-205004 setup_server_error
-205005 setup_retries_exhausted
-205006 setup_no_data_network
-205007 setup_completed
-
-205008 gls_account_tried (status|1)
-205009 gls_account_saved (status|1)
-205010 gls_authenticate (status|1),(service|3)
-205011 google_mail_switch (direction|1)
diff --git a/common/java/com/android/common/NetworkConnectivityListener.java b/common/java/com/android/common/NetworkConnectivityListener.java
deleted file mode 100644
index b49b80d..0000000
--- a/common/java/com/android/common/NetworkConnectivityListener.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright (C) 2006 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.common;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-
-import java.util.HashMap;
-import java.util.Iterator;
-
-/**
- * A wrapper for a broadcast receiver that provides network connectivity
- * state information, independent of network type (mobile, Wi-Fi, etc.).
- * @deprecated Code tempted to use this class should simply listen for connectivity intents
- * (or poll ConnectivityManager) directly.
- * {@hide}
- */
-public class NetworkConnectivityListener {
- private static final String TAG = "NetworkConnectivityListener";
- private static final boolean DBG = false;
-
- private Context mContext;
- private HashMap<Handler, Integer> mHandlers = new HashMap<Handler, Integer>();
- private State mState;
- private boolean mListening;
- private String mReason;
- private boolean mIsFailover;
-
- /** Network connectivity information */
- private NetworkInfo mNetworkInfo;
-
- /**
- * In case of a Disconnect, the connectivity manager may have
- * already established, or may be attempting to establish, connectivity
- * with another network. If so, {@code mOtherNetworkInfo} will be non-null.
- */
- private NetworkInfo mOtherNetworkInfo;
-
- private ConnectivityBroadcastReceiver mReceiver;
-
- private class ConnectivityBroadcastReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
-
- if (!action.equals(ConnectivityManager.CONNECTIVITY_ACTION) ||
- mListening == false) {
- Log.w(TAG, "onReceived() called with " + mState.toString() + " and " + intent);
- return;
- }
-
- boolean noConnectivity =
- intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
-
- if (noConnectivity) {
- mState = State.NOT_CONNECTED;
- } else {
- mState = State.CONNECTED;
- }
-
- mNetworkInfo = (NetworkInfo)
- intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
- mOtherNetworkInfo = (NetworkInfo)
- intent.getParcelableExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO);
-
- mReason = intent.getStringExtra(ConnectivityManager.EXTRA_REASON);
- mIsFailover =
- intent.getBooleanExtra(ConnectivityManager.EXTRA_IS_FAILOVER, false);
-
- if (DBG) {
- Log.d(TAG, "onReceive(): mNetworkInfo=" + mNetworkInfo + " mOtherNetworkInfo = "
- + (mOtherNetworkInfo == null ? "[none]" : mOtherNetworkInfo +
- " noConn=" + noConnectivity) + " mState=" + mState.toString());
- }
-
- // Notifiy any handlers.
- Iterator<Handler> it = mHandlers.keySet().iterator();
- while (it.hasNext()) {
- Handler target = it.next();
- Message message = Message.obtain(target, mHandlers.get(target));
- target.sendMessage(message);
- }
- }
- };
-
- public enum State {
- UNKNOWN,
-
- /** This state is returned if there is connectivity to any network **/
- CONNECTED,
- /**
- * This state is returned if there is no connectivity to any network. This is set
- * to true under two circumstances:
- * <ul>
- * <li>When connectivity is lost to one network, and there is no other available
- * network to attempt to switch to.</li>
- * <li>When connectivity is lost to one network, and the attempt to switch to
- * another network fails.</li>
- */
- NOT_CONNECTED
- }
-
- /**
- * Create a new NetworkConnectivityListener.
- */
- public NetworkConnectivityListener() {
- mState = State.UNKNOWN;
- mReceiver = new ConnectivityBroadcastReceiver();
- }
-
- /**
- * This method starts listening for network connectivity state changes.
- * @param context
- */
- public synchronized void startListening(Context context) {
- if (!mListening) {
- mContext = context;
-
- IntentFilter filter = new IntentFilter();
- filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
- context.registerReceiver(mReceiver, filter);
- mListening = true;
- }
- }
-
- /**
- * This method stops this class from listening for network changes.
- */
- public synchronized void stopListening() {
- if (mListening) {
- mContext.unregisterReceiver(mReceiver);
- mContext = null;
- mNetworkInfo = null;
- mOtherNetworkInfo = null;
- mIsFailover = false;
- mReason = null;
- mListening = false;
- }
- }
-
- /**
- * This methods registers a Handler to be called back onto with the specified what code when
- * the network connectivity state changes.
- *
- * @param target The target handler.
- * @param what The what code to be used when posting a message to the handler.
- */
- public void registerHandler(Handler target, int what) {
- mHandlers.put(target, what);
- }
-
- /**
- * This methods unregisters the specified Handler.
- * @param target
- */
- public void unregisterHandler(Handler target) {
- mHandlers.remove(target);
- }
-
- public State getState() {
- return mState;
- }
-
- /**
- * Return the NetworkInfo associated with the most recent connectivity event.
- * @return {@code NetworkInfo} for the network that had the most recent connectivity event.
- */
- public NetworkInfo getNetworkInfo() {
- return mNetworkInfo;
- }
-
- /**
- * If the most recent connectivity event was a DISCONNECT, return
- * any information supplied in the broadcast about an alternate
- * network that might be available. If this returns a non-null
- * value, then another broadcast should follow shortly indicating
- * whether connection to the other network succeeded.
- *
- * @return NetworkInfo
- */
- public NetworkInfo getOtherNetworkInfo() {
- return mOtherNetworkInfo;
- }
-
- /**
- * Returns true if the most recent event was for an attempt to switch over to
- * a new network following loss of connectivity on another network.
- * @return {@code true} if this was a failover attempt, {@code false} otherwise.
- */
- public boolean isFailover() {
- return mIsFailover;
- }
-
- /**
- * An optional reason for the connectivity state change may have been supplied.
- * This returns it.
- * @return the reason for the state change, if available, or {@code null}
- * otherwise.
- */
- public String getReason() {
- return mReason;
- }
-}
diff --git a/common/java/com/android/common/OperationScheduler.java b/common/java/com/android/common/OperationScheduler.java
deleted file mode 100644
index 1786957..0000000
--- a/common/java/com/android/common/OperationScheduler.java
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Copyright (C) 2009 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.common;
-
-import android.content.SharedPreferences;
-import android.net.http.AndroidHttpClient;
-import android.text.format.Time;
-
-import java.util.Map;
-import java.util.TreeSet;
-
-/**
- * Tracks the success/failure history of a particular network operation in
- * persistent storage and computes retry strategy accordingly. Handles
- * exponential backoff, periodic rescheduling, event-driven triggering,
- * retry-after moratorium intervals, etc. based on caller-specified parameters.
- *
- * <p>This class does not directly perform or invoke any operations,
- * it only keeps track of the schedule. Somebody else needs to call
- * {@link #getNextTimeMillis()} as appropriate and do the actual work.
- */
-public class OperationScheduler {
- /** Tunable parameter options for {@link #getNextTimeMillis}. */
- public static class Options {
- /** Wait this long after every error before retrying. */
- public long backoffFixedMillis = 0;
-
- /** Wait this long times the number of consecutive errors so far before retrying. */
- public long backoffIncrementalMillis = 5000;
-
- /** Maximum duration of moratorium to honor. Mostly an issue for clock rollbacks. */
- public long maxMoratoriumMillis = 24 * 3600 * 1000;
-
- /** Minimum duration after success to wait before allowing another trigger. */
- public long minTriggerMillis = 0;
-
- /** Automatically trigger this long after the last success. */
- public long periodicIntervalMillis = 0;
-
- @Override
- public String toString() {
- return String.format(
- "OperationScheduler.Options[backoff=%.1f+%.1f max=%.1f min=%.1f period=%.1f]",
- backoffFixedMillis / 1000.0, backoffIncrementalMillis / 1000.0,
- maxMoratoriumMillis / 1000.0, minTriggerMillis / 1000.0,
- periodicIntervalMillis / 1000.0);
- }
- }
-
- private static final String PREFIX = "OperationScheduler_";
- private final SharedPreferences mStorage;
-
- /**
- * Initialize the scheduler state.
- * @param storage to use for recording the state of operations across restarts/reboots
- */
- public OperationScheduler(SharedPreferences storage) {
- mStorage = storage;
- }
-
- /**
- * Parse scheduler options supplied in this string form:
- *
- * <pre>
- * backoff=(fixed)+(incremental) max=(maxmoratorium) min=(mintrigger) [period=](interval)
- * </pre>
- *
- * All values are times in (possibly fractional) <em>seconds</em> (not milliseconds).
- * Omitted settings are left at whatever existing default value was passed in.
- *
- * <p>
- * The default options: <code>backoff=0+5 max=86400 min=0 period=0</code><br>
- * Fractions are OK: <code>backoff=+2.5 period=10.0</code><br>
- * The "period=" can be omitted: <code>3600</code><br>
- *
- * @param spec describing some or all scheduler options.
- * @param options to update with parsed values.
- * @return the options passed in (for convenience)
- * @throws IllegalArgumentException if the syntax is invalid
- */
- public static Options parseOptions(String spec, Options options)
- throws IllegalArgumentException {
- for (String param : spec.split(" +")) {
- if (param.length() == 0) continue;
- if (param.startsWith("backoff=")) {
- int plus = param.indexOf('+', 8);
- if (plus < 0) {
- options.backoffFixedMillis = parseSeconds(param.substring(8));
- } else {
- if (plus > 8) {
- options.backoffFixedMillis = parseSeconds(param.substring(8, plus));
- }
- options.backoffIncrementalMillis = parseSeconds(param.substring(plus + 1));
- }
- } else if (param.startsWith("max=")) {
- options.maxMoratoriumMillis = parseSeconds(param.substring(4));
- } else if (param.startsWith("min=")) {
- options.minTriggerMillis = parseSeconds(param.substring(4));
- } else if (param.startsWith("period=")) {
- options.periodicIntervalMillis = parseSeconds(param.substring(7));
- } else {
- options.periodicIntervalMillis = parseSeconds(param);
- }
- }
- return options;
- }
-
- private static long parseSeconds(String param) throws NumberFormatException {
- return (long) (Float.parseFloat(param) * 1000);
- }
-
- /**
- * Compute the time of the next operation. Does not modify any state
- * (unless the clock rolls backwards, in which case timers are reset).
- *
- * @param options to use for this computation.
- * @return the wall clock time ({@link System#currentTimeMillis()}) when the
- * next operation should be attempted -- immediately, if the return value is
- * before the current time.
- */
- public long getNextTimeMillis(Options options) {
- boolean enabledState = mStorage.getBoolean(PREFIX + "enabledState", true);
- if (!enabledState) return Long.MAX_VALUE;
-
- boolean permanentError = mStorage.getBoolean(PREFIX + "permanentError", false);
- if (permanentError) return Long.MAX_VALUE;
-
- // We do quite a bit of limiting to prevent a clock rollback from totally
- // hosing the scheduler. Times which are supposed to be in the past are
- // clipped to the current time so we don't languish forever.
-
- int errorCount = mStorage.getInt(PREFIX + "errorCount", 0);
- long now = currentTimeMillis();
- long lastSuccessTimeMillis = getTimeBefore(PREFIX + "lastSuccessTimeMillis", now);
- long lastErrorTimeMillis = getTimeBefore(PREFIX + "lastErrorTimeMillis", now);
- long triggerTimeMillis = mStorage.getLong(PREFIX + "triggerTimeMillis", Long.MAX_VALUE);
- long moratoriumSetMillis = getTimeBefore(PREFIX + "moratoriumSetTimeMillis", now);
- long moratoriumTimeMillis = getTimeBefore(PREFIX + "moratoriumTimeMillis",
- moratoriumSetMillis + options.maxMoratoriumMillis);
-
- long time = triggerTimeMillis;
- if (options.periodicIntervalMillis > 0) {
- time = Math.min(time, lastSuccessTimeMillis + options.periodicIntervalMillis);
- }
-
- time = Math.max(time, moratoriumTimeMillis);
- time = Math.max(time, lastSuccessTimeMillis + options.minTriggerMillis);
- if (errorCount > 0) {
- time = Math.max(time, lastErrorTimeMillis + options.backoffFixedMillis +
- options.backoffIncrementalMillis * errorCount);
- }
- return time;
- }
-
- /**
- * Return the last time the operation completed. Does not modify any state.
- *
- * @return the wall clock time when {@link #onSuccess()} was last called.
- */
- public long getLastSuccessTimeMillis() {
- return mStorage.getLong(PREFIX + "lastSuccessTimeMillis", 0);
- }
-
- /**
- * Return the last time the operation was attempted. Does not modify any state.
- *
- * @return the wall clock time when {@link #onSuccess()} or {@link
- * #onTransientError()} was last called.
- */
- public long getLastAttemptTimeMillis() {
- return Math.max(
- mStorage.getLong(PREFIX + "lastSuccessTimeMillis", 0),
- mStorage.getLong(PREFIX + "lastErrorTimeMillis", 0));
- }
-
- /**
- * Fetch a {@link SharedPreferences} property, but force it to be before
- * a certain time, updating the value if necessary. This is to recover
- * gracefully from clock rollbacks which could otherwise strand our timers.
- *
- * @param name of SharedPreferences key
- * @param max time to allow in result
- * @return current value attached to key (default 0), limited by max
- */
- private long getTimeBefore(String name, long max) {
- long time = mStorage.getLong(name, 0);
- if (time > max) mStorage.edit().putLong(name, (time = max)).commit();
- return time;
- }
-
- /**
- * Request an operation to be performed at a certain time. The actual
- * scheduled time may be affected by error backoff logic and defined
- * minimum intervals. Use {@link Long#MAX_VALUE} to disable triggering.
- *
- * @param millis wall clock time ({@link System#currentTimeMillis()}) to
- * trigger another operation; 0 to trigger immediately
- */
- public void setTriggerTimeMillis(long millis) {
- mStorage.edit().putLong(PREFIX + "triggerTimeMillis", millis).commit();
- }
-
- /**
- * Forbid any operations until after a certain (absolute) time.
- * Limited by {@link #Options.maxMoratoriumMillis}.
- *
- * @param millis wall clock time ({@link System#currentTimeMillis()})
- * when operations should be allowed again; 0 to remove moratorium
- */
- public void setMoratoriumTimeMillis(long millis) {
- mStorage.edit()
- .putLong(PREFIX + "moratoriumTimeMillis", millis)
- .putLong(PREFIX + "moratoriumSetTimeMillis", currentTimeMillis())
- .commit();
- }
-
- /**
- * Forbid any operations until after a certain time, as specified in
- * the format used by the HTTP "Retry-After" header.
- * Limited by {@link #Options.maxMoratoriumMillis}.
- *
- * @param retryAfter moratorium time in HTTP format
- * @return true if a time was successfully parsed
- */
- public boolean setMoratoriumTimeHttp(String retryAfter) {
- try {
- long ms = Long.valueOf(retryAfter) * 1000;
- setMoratoriumTimeMillis(ms + currentTimeMillis());
- return true;
- } catch (NumberFormatException nfe) {
- try {
- setMoratoriumTimeMillis(AndroidHttpClient.parseDate(retryAfter));
- return true;
- } catch (IllegalArgumentException iae) {
- return false;
- }
- }
- }
-
- /**
- * Enable or disable all operations. When disabled, all calls to
- * {@link #getNextTimeMillis()} return {@link Long#MAX_VALUE}.
- * Commonly used when data network availability goes up and down.
- *
- * @param enabled if operations can be performed
- */
- public void setEnabledState(boolean enabled) {
- mStorage.edit().putBoolean(PREFIX + "enabledState", enabled).commit();
- }
-
- /**
- * Report successful completion of an operation. Resets all error
- * counters, clears any trigger directives, and records the success.
- */
- public void onSuccess() {
- resetTransientError();
- resetPermanentError();
- mStorage.edit()
- .remove(PREFIX + "errorCount")
- .remove(PREFIX + "lastErrorTimeMillis")
- .remove(PREFIX + "permanentError")
- .remove(PREFIX + "triggerTimeMillis")
- .putLong(PREFIX + "lastSuccessTimeMillis", currentTimeMillis()).commit();
- }
-
- /**
- * Report a transient error (usually a network failure). Increments
- * the error count and records the time of the latest error for backoff
- * purposes.
- */
- public void onTransientError() {
- mStorage.edit().putLong(PREFIX + "lastErrorTimeMillis", currentTimeMillis()).commit();
- mStorage.edit().putInt(PREFIX + "errorCount",
- mStorage.getInt(PREFIX + "errorCount", 0) + 1).commit();
- }
-
- /**
- * Reset all transient error counts, allowing the next operation to proceed
- * immediately without backoff. Commonly used on network state changes, when
- * partial progress occurs (some data received), and in other circumstances
- * where there is reason to hope things might start working better.
- */
- public void resetTransientError() {
- mStorage.edit().remove(PREFIX + "errorCount").commit();
- }
-
- /**
- * Report a permanent error that will not go away until further notice.
- * No operation will be scheduled until {@link #resetPermanentError()}
- * is called. Commonly used for authentication failures (which are reset
- * when the accounts database is updated).
- */
- public void onPermanentError() {
- mStorage.edit().putBoolean(PREFIX + "permanentError", true).commit();
- }
-
- /**
- * Reset any permanent error status set by {@link #onPermanentError},
- * allowing operations to be scheduled as normal.
- */
- public void resetPermanentError() {
- mStorage.edit().remove(PREFIX + "permanentError").commit();
- }
-
- /**
- * Return a string description of the scheduler state for debugging.
- */
- public String toString() {
- StringBuilder out = new StringBuilder("[OperationScheduler:");
- for (String key : new TreeSet<String>(mStorage.getAll().keySet())) { // Sort keys
- if (key.startsWith(PREFIX)) {
- if (key.endsWith("TimeMillis")) {
- Time time = new Time();
- time.set(mStorage.getLong(key, 0));
- out.append(" ").append(key.substring(PREFIX.length(), key.length() - 10));
- out.append("=").append(time.format("%Y-%m-%d/%H:%M:%S"));
- } else {
- out.append(" ").append(key.substring(PREFIX.length()));
- out.append("=").append(mStorage.getAll().get(key).toString());
- }
- }
- }
- return out.append("]").toString();
- }
-
- /**
- * Gets the current time. Can be overridden for unit testing.
- *
- * @return {@link System#currentTimeMillis()}
- */
- protected long currentTimeMillis() {
- return System.currentTimeMillis();
- }
-}
diff --git a/common/java/com/android/common/Rfc822InputFilter.java b/common/java/com/android/common/Rfc822InputFilter.java
deleted file mode 100644
index 6dfdc7b..0000000
--- a/common/java/com/android/common/Rfc822InputFilter.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2008 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.common;
-
-import android.text.InputFilter;
-import android.text.Spanned;
-import android.text.SpannableStringBuilder;
-
-/**
- * Implements special address cleanup rules:
- * The first space key entry following an "@" symbol that is followed by any combination
- * of letters and symbols, including one+ dots and zero commas, should insert an extra
- * comma (followed by the space).
- *
- * @hide
- */
-public class Rfc822InputFilter implements InputFilter {
-
- public CharSequence filter(CharSequence source, int start, int end, Spanned dest,
- int dstart, int dend) {
-
- // quick check - did they enter a single space?
- if (end-start != 1 || source.charAt(start) != ' ') {
- return null;
- }
-
- // determine if the characters before the new space fit the pattern
- // follow backwards and see if we find a comma, dot, or @
- int scanBack = dstart;
- boolean dotFound = false;
- while (scanBack > 0) {
- char c = dest.charAt(--scanBack);
- switch (c) {
- case '.':
- dotFound = true; // one or more dots are req'd
- break;
- case ',':
- return null;
- case '@':
- if (!dotFound) {
- return null;
- }
- // we have found a comma-insert case. now just do it
- // in the least expensive way we can.
- if (source instanceof Spanned) {
- SpannableStringBuilder sb = new SpannableStringBuilder(",");
- sb.append(source);
- return sb;
- } else {
- return ", ";
- }
- default:
- // just keep going
- }
- }
-
- // no termination cases were found, so don't edit the input
- return null;
- }
-}
diff --git a/common/java/com/android/common/Rfc822Validator.java b/common/java/com/android/common/Rfc822Validator.java
deleted file mode 100644
index 087e425..0000000
--- a/common/java/com/android/common/Rfc822Validator.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2008 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.common;
-
-import android.text.TextUtils;
-import android.text.util.Rfc822Token;
-import android.text.util.Rfc822Tokenizer;
-import android.widget.AutoCompleteTextView;
-
-import java.util.regex.Pattern;
-
-/**
- * This class works as a Validator for AutoCompleteTextView for
- * email addresses. If a token does not appear to be a valid address,
- * it is trimmed of characters that cannot legitimately appear in one
- * and has the specified domain name added. It is meant for use with
- * {@link Rfc822Token} and {@link Rfc822Tokenizer}.
- *
- * @deprecated In the future make sure we don't quietly alter the user's
- * text in ways they did not intend. Meanwhile, hide this
- * class from the public API because it does not even have
- * a full understanding of the syntax it claims to correct.
- * @hide
- */
-public class Rfc822Validator implements AutoCompleteTextView.Validator {
- /*
- * Regex.EMAIL_ADDRESS_PATTERN hardcodes the TLD that we accept, but we
- * want to make sure we will keep accepting email addresses with TLD's
- * that don't exist at the time of this writing, so this regexp relaxes
- * that constraint by accepting any kind of top level domain, not just
- * ".com", ".fr", etc...
- */
- private static final Pattern EMAIL_ADDRESS_PATTERN =
- Pattern.compile("[^\\s@]+@[^\\s@]+\\.[a-zA-z][a-zA-Z][a-zA-Z]*");
-
- private String mDomain;
-
- /**
- * Constructs a new validator that uses the specified domain name as
- * the default when none is specified.
- */
- public Rfc822Validator(String domain) {
- mDomain = domain;
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean isValid(CharSequence text) {
- Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(text);
-
- return tokens.length == 1 &&
- EMAIL_ADDRESS_PATTERN.
- matcher(tokens[0].getAddress()).matches();
- }
-
- /**
- * @return a string in which all the characters that are illegal for the username
- * or the domain name part of the email address have been removed.
- */
- private String removeIllegalCharacters(String s) {
- StringBuilder result = new StringBuilder();
- int length = s.length();
- for (int i = 0; i < length; i++) {
- char c = s.charAt(i);
-
- /*
- * An RFC822 atom can contain any ASCII printing character
- * except for periods and any of the following punctuation.
- * A local-part can contain multiple atoms, concatenated by
- * periods, so do allow periods here.
- */
-
- if (c <= ' ' || c > '~') {
- continue;
- }
-
- if (c == '(' || c == ')' || c == '<' || c == '>' ||
- c == '@' || c == ',' || c == ';' || c == ':' ||
- c == '\\' || c == '"' || c == '[' || c == ']') {
- continue;
- }
-
- result.append(c);
- }
- return result.toString();
- }
-
- /**
- * {@inheritDoc}
- */
- public CharSequence fixText(CharSequence cs) {
- // Return an empty string if the email address only contains spaces, \n or \t
- if (TextUtils.getTrimmedLength(cs) == 0) return "";
-
- Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(cs);
- StringBuilder sb = new StringBuilder();
-
- for (int i = 0; i < tokens.length; i++) {
- String text = tokens[i].getAddress();
- int index = text.indexOf('@');
- if (index < 0) {
- // If there is no @, just append the domain of the account
- tokens[i].setAddress(removeIllegalCharacters(text) + "@" + mDomain);
- } else {
- // Otherwise, remove the illegal characters on both sides of the '@'
- String fix = removeIllegalCharacters(text.substring(0, index));
- String domain = removeIllegalCharacters(text.substring(index + 1));
- tokens[i].setAddress(fix + "@" + (domain.length() != 0 ? domain : mDomain));
- }
-
- sb.append(tokens[i].toString());
- if (i + 1 < tokens.length) {
- sb.append(", ");
- }
- }
-
- return sb;
- }
-}
diff --git a/common/java/com/android/common/Search.java b/common/java/com/android/common/Search.java
deleted file mode 100644
index 55fa6f5..0000000
--- a/common/java/com/android/common/Search.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.common;
-
-/**
- * Utilities for search implementations.
- *
- * @see android.app.SearchManager
- */
-public class Search {
-
- /**
- * Key for the source identifier set by the application that launched a search intent.
- * The identifier is search-source specific string. It can be used
- * by the search provider to keep statistics of where searches are started from.
- *
- * The source identifier is stored in the {@link android.app.SearchManager#APP_DATA}
- * Bundle in {@link android.content.Intent#ACTION_SEARCH} and
- * {@link android.content.Intent#ACTION_WEB_SEARCH} intents.
- */
- public final static String SOURCE = "source";
-
- private Search() { } // don't instantiate
-}
diff --git a/common/java/com/android/common/speech/LoggingEvents.java b/common/java/com/android/common/speech/LoggingEvents.java
deleted file mode 100644
index 1f3c6ef..0000000
--- a/common/java/com/android/common/speech/LoggingEvents.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * 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.common.speech;
-
-/**
- * Logging event constants used for Voice Search and VoiceIME. These are the
- * keys and values of extras to be specified in logging broadcast intents.
- * This class is used by clients of the android.speech APIs to log how the
- * user interacts with the IME settings and speech recognition result.
- */
-public class LoggingEvents {
- // The name of the broadcast intent for logging.
- public static final String ACTION_LOG_EVENT = "com.android.common.speech.LOG_EVENT";
-
- // The extra key used for the name of the app being logged.
- public static final String EXTRA_APP_NAME = "app_name";
-
- // The extra key used for the name of the app issuing the VoiceSearch
- // or VoiceIME request
- public static final String EXTRA_CALLING_APP_NAME = "";
-
- // The extra key used for the event value. The possible event values depend
- // on the app being logged for, and are defined in the subclasses below.
- public static final String EXTRA_EVENT = "extra_event";
-
- // The extra key used to log the time in milliseconds at which the EXTRA_EVENT
- // occurred in the client.
- public static final String EXTRA_TIMESTAMP = "timestamp";
-
- // The extra key used (with a boolean value of 'true') as a way to trigger a
- // flush of the log events to the server.
- public static final String EXTRA_FLUSH = "flush";
-
- /**
- * Logging event constants for voice search. Below are the extra values for
- * {@link LoggingEvents#EXTRA_EVENT}, clustered with keys to additional
- * extras for some events that need to be included as additional fields in
- * the event. Note that this is not representative of *all* voice search
- * events - only the ones that need to be reported from outside the voice
- * search app, such as from Browser.
- */
- public class VoiceSearch {
- // The app name to be used for logging VoiceSearch events.
- public static final String APP_NAME = "googlemobile";
-
- public static final int RETRY = 0;
-
- public static final int N_BEST_REVEAL = 1;
-
- public static final int N_BEST_CHOOSE = 2;
- public static final String EXTRA_N_BEST_CHOOSE_INDEX = "index"; // value should be int
-
- public static final int QUERY_UPDATED = 3;
- public static final String EXTRA_QUERY_UPDATED_VALUE = "value"; // value should be String
- }
-
- /**
- * Logging event constants for VoiceIME. Below are the extra values for
- * {@link LoggingEvents#EXTRA_EVENT}, clustered with keys to additional
- * extras for some events that need to be included as additional fields in
- * the event.
- */
- public class VoiceIme {
- // The app name to be used for logging VoiceIME events.
- public static final String APP_NAME = "voiceime";
-
- public static final int KEYBOARD_WARNING_DIALOG_SHOWN = 0;
-
- public static final int KEYBOARD_WARNING_DIALOG_DISMISSED = 1;
-
- public static final int KEYBOARD_WARNING_DIALOG_OK = 2;
-
- public static final int KEYBOARD_WARNING_DIALOG_CANCEL = 3;
-
- public static final int SETTINGS_WARNING_DIALOG_SHOWN = 4;
-
- public static final int SETTINGS_WARNING_DIALOG_DISMISSED = 5;
-
- public static final int SETTINGS_WARNING_DIALOG_OK = 6;
-
- public static final int SETTINGS_WARNING_DIALOG_CANCEL = 7;
-
- public static final int SWIPE_HINT_DISPLAYED = 8;
-
- public static final int PUNCTUATION_HINT_DISPLAYED = 9;
-
- public static final int CANCEL_DURING_LISTENING = 10;
-
- public static final int CANCEL_DURING_WORKING = 11;
-
- public static final int CANCEL_DURING_ERROR = 12;
-
- public static final int ERROR = 13;
- public static final String EXTRA_ERROR_CODE = "code"; // value should be int
-
- public static final int START = 14;
- public static final String EXTRA_START_LOCALE = "locale"; // value should be String
- public static final String EXTRA_START_SWIPE = "swipe"; // value should be boolean
-
- public static final int VOICE_INPUT_DELIVERED = 15;
-
- public static final int N_BEST_CHOOSE = 16;
- public static final String EXTRA_N_BEST_CHOOSE_INDEX = "index"; // value should be int
-
- public static final int TEXT_MODIFIED = 17;
- public static final String EXTRA_TEXT_MODIFIED_LENGTH = "length"; // value should be int
- public static final String EXTRA_TEXT_MODIFIED_TYPE = "type"; // value should be int below
- public static final int TEXT_MODIFIED_TYPE_CHOOSE_SUGGESTION = 1;
- public static final int TEXT_MODIFIED_TYPE_TYPING_DELETION = 2;
- public static final int TEXT_MODIFIED_TYPE_TYPING_INSERTION = 3;
- public static final int TEXT_MODIFIED_TYPE_TYPING_INSERTION_PUNCTUATION = 4;
-
- public static final int INPUT_ENDED = 18;
-
- public static final int VOICE_INPUT_SETTING_ENABLED = 19;
-
- public static final int VOICE_INPUT_SETTING_DISABLED = 20;
-
- public static final int IME_TEXT_ACCEPTED = 21;
- }
-
-}
diff --git a/common/java/com/android/common/speech/Recognition.java b/common/java/com/android/common/speech/Recognition.java
deleted file mode 100644
index 1970179..0000000
--- a/common/java/com/android/common/speech/Recognition.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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.common.speech;
-
-/**
- * Utilities for voice recognition implementations.
- *
- * @see android.speech.RecognitionService
- * @see android.speech.RecognizerIntent
- */
-public class Recognition {
-
- /**
- * The key to the extra in the Bundle returned by
- * android.speech.RecognizerIntent#ACTION_GET_LANGUAGE_DETAILS
- * which is an ArrayList of CharSequences which are hints that can be shown to
- * the user for voice actions currently supported by voice search for the user's current
- * language preference for voice search (i.e., the one defined in the extra
- * android.speech.RecognizerIntent#EXTRA_LANGUAGE_PREFERENCE).
- *
- * If this is paired with EXTRA_HINT_CONTEXT, should return a set of hints that are
- * appropriate for the provided context.
- *
- * The CharSequences are SpannedStrings and will contain segments wrapped in
- * <annotation action="true"></annotation>. This is to indicate the section of the text
- * which represents the voice action, to be highlighted in the UI if so desired.
- */
- public static final String EXTRA_HINT_STRINGS = "android.speech.extra.HINT_STRINGS";
-
- /**
- * The key to an extra to be included in the request intent for
- * android.speech.RecognizerIntent#ACTION_GET_LANGUAGE_DETAILS.
- * Should be an int of one of the values defined below. If an
- * unknown int value is provided, it should be ignored.
- */
- public static final String EXTRA_HINT_CONTEXT = "android.speech.extra.HINT_CONTEXT";
-
- /**
- * A set of values for EXTRA_HINT_CONTEXT.
- */
- public static final int HINT_CONTEXT_UNKNOWN = 0;
- public static final int HINT_CONTEXT_VOICE_SEARCH_HELP = 1;
- public static final int HINT_CONTEXT_CAR_HOME = 2;
- public static final int HINT_CONTEXT_LAUNCHER = 3;
-
- private Recognition() { } // don't instantiate
-}
diff --git a/common/java/com/android/common/userhappiness/UserHappinessSignals.java b/common/java/com/android/common/userhappiness/UserHappinessSignals.java
deleted file mode 100644
index 347bdaa..0000000
--- a/common/java/com/android/common/userhappiness/UserHappinessSignals.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.common.userhappiness;
-
-import android.content.Intent;
-import android.content.Context;
-import com.android.common.speech.LoggingEvents;
-
-/**
- * Metrics for User Happiness are recorded here. Each app can define when to
- * call these User Happiness metrics.
- */
-public class UserHappinessSignals {
-
- /**
- * Log when a user "accepted" IME text. Each application can define what
- * it means to "accept" text. In the case of Gmail, pressing the "Send"
- * button indicates text acceptance. We broadcast this information to
- * VoiceSearch LoggingEvents and use it to aggregate VoiceIME Happiness Metrics
- */
- public static void userAcceptedImeText(Context context) {
- // Create a Voice IME Logging intent.
- Intent i = new Intent(LoggingEvents.ACTION_LOG_EVENT);
- i.putExtra(LoggingEvents.EXTRA_APP_NAME, LoggingEvents.VoiceIme.APP_NAME);
- i.putExtra(LoggingEvents.EXTRA_EVENT, LoggingEvents.VoiceIme.IME_TEXT_ACCEPTED);
- i.putExtra(LoggingEvents.EXTRA_CALLING_APP_NAME, context.getPackageName());
- i.putExtra(LoggingEvents.EXTRA_TIMESTAMP, System.currentTimeMillis());
- context.sendBroadcast(i);
- }
-
-}
diff --git a/common/tests/Android.mk b/common/tests/Android.mk
deleted file mode 100644
index 74255521..0000000
--- a/common/tests/Android.mk
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2009 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.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_CERTIFICATE := platform
-LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_MODULE_TAGS := tests
-LOCAL_PACKAGE_NAME := AndroidCommonTests
-LOCAL_SDK_VERSION := current
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_STATIC_JAVA_LIBRARIES := android-common
-
-LOCAL_PROGUARD_ENABLED := disabled
-
-include $(BUILD_PACKAGE)
diff --git a/common/tests/AndroidManifest.xml b/common/tests/AndroidManifest.xml
deleted file mode 100644
index 151ec20..0000000
--- a/common/tests/AndroidManifest.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.common.tests"
- android:sharedUserId="com.android.uid.test">
-
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-
- <!-- Run tests with "runtest common" -->
- <instrumentation android:name="android.test.InstrumentationTestRunner"
- android:targetPackage="com.android.common.tests"
- android:label="Android Common Library Tests" />
-
-</manifest>
diff --git a/common/tests/src/com/android/common/OperationSchedulerTest.java b/common/tests/src/com/android/common/OperationSchedulerTest.java
deleted file mode 100644
index 955508f..0000000
--- a/common/tests/src/com/android/common/OperationSchedulerTest.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (C) 2009 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.common;
-
-import android.content.SharedPreferences;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.SmallTest;
-
-public class OperationSchedulerTest extends AndroidTestCase {
- /**
- * OperationScheduler subclass which uses an artificial time.
- * Set {@link #timeMillis} to whatever value you like.
- */
- private class TimeTravelScheduler extends OperationScheduler {
- static final long DEFAULT_TIME = 1250146800000L; // 13-Aug-2009, 12:00:00 am
- public long timeMillis = DEFAULT_TIME;
-
- @Override
- protected long currentTimeMillis() { return timeMillis; }
- public TimeTravelScheduler() { super(getFreshStorage()); }
- }
-
- private SharedPreferences getFreshStorage() {
- SharedPreferences sp = getContext().getSharedPreferences("OperationSchedulerTest", 0);
- sp.edit().clear().commit();
- return sp;
- }
-
- @MediumTest
- public void testScheduler() throws Exception {
- TimeTravelScheduler scheduler = new TimeTravelScheduler();
- OperationScheduler.Options options = new OperationScheduler.Options();
- assertEquals(Long.MAX_VALUE, scheduler.getNextTimeMillis(options));
- assertEquals(0, scheduler.getLastSuccessTimeMillis());
- assertEquals(0, scheduler.getLastAttemptTimeMillis());
-
- long beforeTrigger = scheduler.timeMillis;
- scheduler.setTriggerTimeMillis(beforeTrigger + 1000000);
- assertEquals(beforeTrigger + 1000000, scheduler.getNextTimeMillis(options));
-
- // It will schedule for the later of the trigger and the moratorium...
- scheduler.setMoratoriumTimeMillis(beforeTrigger + 500000);
- assertEquals(beforeTrigger + 1000000, scheduler.getNextTimeMillis(options));
- scheduler.setMoratoriumTimeMillis(beforeTrigger + 1500000);
- assertEquals(beforeTrigger + 1500000, scheduler.getNextTimeMillis(options));
-
- // Test enable/disable toggle
- scheduler.setEnabledState(false);
- assertEquals(Long.MAX_VALUE, scheduler.getNextTimeMillis(options));
- scheduler.setEnabledState(true);
- assertEquals(beforeTrigger + 1500000, scheduler.getNextTimeMillis(options));
-
- // Backoff interval after an error
- long beforeError = (scheduler.timeMillis += 100);
- scheduler.onTransientError();
- assertEquals(0, scheduler.getLastSuccessTimeMillis());
- assertEquals(beforeError, scheduler.getLastAttemptTimeMillis());
- assertEquals(beforeTrigger + 1500000, scheduler.getNextTimeMillis(options));
- options.backoffFixedMillis = 1000000;
- options.backoffIncrementalMillis = 500000;
- assertEquals(beforeError + 1500000, scheduler.getNextTimeMillis(options));
-
- // Two errors: backoff interval increases
- beforeError = (scheduler.timeMillis += 100);
- scheduler.onTransientError();
- assertEquals(beforeError, scheduler.getLastAttemptTimeMillis());
- assertEquals(beforeError + 2000000, scheduler.getNextTimeMillis(options));
-
- // Reset transient error: no backoff interval
- scheduler.resetTransientError();
- assertEquals(0, scheduler.getLastSuccessTimeMillis());
- assertEquals(beforeTrigger + 1500000, scheduler.getNextTimeMillis(options));
- assertEquals(beforeError, scheduler.getLastAttemptTimeMillis());
-
- // Permanent error holds true even if transient errors are reset
- // However, we remember that the transient error was reset...
- scheduler.onPermanentError();
- assertEquals(Long.MAX_VALUE, scheduler.getNextTimeMillis(options));
- scheduler.resetTransientError();
- assertEquals(Long.MAX_VALUE, scheduler.getNextTimeMillis(options));
- scheduler.resetPermanentError();
- assertEquals(beforeTrigger + 1500000, scheduler.getNextTimeMillis(options));
-
- // Success resets the trigger
- long beforeSuccess = (scheduler.timeMillis += 100);
- scheduler.onSuccess();
- assertEquals(beforeSuccess, scheduler.getLastAttemptTimeMillis());
- assertEquals(beforeSuccess, scheduler.getLastSuccessTimeMillis());
- assertEquals(Long.MAX_VALUE, scheduler.getNextTimeMillis(options));
-
- // The moratorium is not reset by success!
- scheduler.setTriggerTimeMillis(0);
- assertEquals(beforeTrigger + 1500000, scheduler.getNextTimeMillis(options));
- scheduler.setMoratoriumTimeMillis(0);
- assertEquals(beforeSuccess, scheduler.getNextTimeMillis(options));
-
- // Periodic interval after success
- options.periodicIntervalMillis = 250000;
- scheduler.setTriggerTimeMillis(Long.MAX_VALUE);
- assertEquals(beforeSuccess + 250000, scheduler.getNextTimeMillis(options));
-
- // Trigger minimum is also since the last success
- options.minTriggerMillis = 1000000;
- assertEquals(beforeSuccess + 1000000, scheduler.getNextTimeMillis(options));
- }
-
- @SmallTest
- public void testParseOptions() throws Exception {
- OperationScheduler.Options options = new OperationScheduler.Options();
- assertEquals(
- "OperationScheduler.Options[backoff=0.0+5.0 max=86400.0 min=0.0 period=3600.0]",
- OperationScheduler.parseOptions("3600", options).toString());
-
- assertEquals(
- "OperationScheduler.Options[backoff=0.0+2.5 max=86400.0 min=0.0 period=3700.0]",
- OperationScheduler.parseOptions("backoff=+2.5 3700", options).toString());
-
- assertEquals(
- "OperationScheduler.Options[backoff=10.0+2.5 max=12345.6 min=7.0 period=3800.0]",
- OperationScheduler.parseOptions("max=12345.6 min=7 backoff=10 period=3800",
- options).toString());
-
- assertEquals(
- "OperationScheduler.Options[backoff=10.0+2.5 max=12345.6 min=7.0 period=3800.0]",
- OperationScheduler.parseOptions("", options).toString());
- }
-
- @SmallTest
- public void testMoratoriumWithHttpDate() throws Exception {
- TimeTravelScheduler scheduler = new TimeTravelScheduler();
- OperationScheduler.Options options = new OperationScheduler.Options();
-
- long beforeTrigger = scheduler.timeMillis;
- scheduler.setTriggerTimeMillis(beforeTrigger + 1000000);
- assertEquals(beforeTrigger + 1000000, scheduler.getNextTimeMillis(options));
-
- scheduler.setMoratoriumTimeMillis(beforeTrigger + 2000000);
- assertEquals(beforeTrigger + 2000000, scheduler.getNextTimeMillis(options));
-
- long beforeMoratorium = scheduler.timeMillis;
- assertTrue(scheduler.setMoratoriumTimeHttp("3000"));
- long afterMoratorium = scheduler.timeMillis;
- assertTrue(beforeMoratorium + 3000000 <= scheduler.getNextTimeMillis(options));
- assertTrue(afterMoratorium + 3000000 >= scheduler.getNextTimeMillis(options));
-
- options.maxMoratoriumMillis = Long.MAX_VALUE / 2;
- assertTrue(scheduler.setMoratoriumTimeHttp("Fri, 31 Dec 2030 23:59:59 GMT"));
- assertEquals(1924991999000L, scheduler.getNextTimeMillis(options));
-
- assertFalse(scheduler.setMoratoriumTimeHttp("not actually a date"));
- }
-
- @SmallTest
- public void testClockRollbackScenario() throws Exception {
- TimeTravelScheduler scheduler = new TimeTravelScheduler();
- OperationScheduler.Options options = new OperationScheduler.Options();
- options.minTriggerMillis = 2000;
-
- // First, set up a scheduler with reasons to wait: a transient
- // error with backoff and a moratorium for a few minutes.
-
- long beforeTrigger = scheduler.timeMillis;
- long triggerTime = beforeTrigger - 10000000;
- scheduler.setTriggerTimeMillis(triggerTime);
- assertEquals(triggerTime, scheduler.getNextTimeMillis(options));
- assertEquals(0, scheduler.getLastAttemptTimeMillis());
-
- long beforeSuccess = (scheduler.timeMillis += 100);
- scheduler.onSuccess();
- scheduler.setTriggerTimeMillis(triggerTime);
- assertEquals(beforeSuccess, scheduler.getLastAttemptTimeMillis());
- assertEquals(beforeSuccess + 2000, scheduler.getNextTimeMillis(options));
-
- long beforeError = (scheduler.timeMillis += 100);
- scheduler.onTransientError();
- assertEquals(beforeError, scheduler.getLastAttemptTimeMillis());
- assertEquals(beforeError + 5000, scheduler.getNextTimeMillis(options));
-
- long beforeMoratorium = (scheduler.timeMillis += 100);
- scheduler.setMoratoriumTimeMillis(beforeTrigger + 1000000);
- assertEquals(beforeTrigger + 1000000, scheduler.getNextTimeMillis(options));
-
- // Now set the time back a few seconds.
- // The moratorium time should still be honored.
- long beforeRollback = (scheduler.timeMillis = beforeTrigger - 10000);
- assertEquals(beforeTrigger + 1000000, scheduler.getNextTimeMillis(options));
-
- // The rollback also moved the last-attempt clock back to the rollback time.
- assertEquals(scheduler.timeMillis, scheduler.getLastAttemptTimeMillis());
-
- // But if we set the time back more than a day, the moratorium
- // resets to the maximum moratorium (a day, by default), exposing
- // the original trigger time.
- beforeRollback = (scheduler.timeMillis = beforeTrigger - 100000000);
- assertEquals(triggerTime, scheduler.getNextTimeMillis(options));
- assertEquals(beforeRollback, scheduler.getLastAttemptTimeMillis());
-
- // If we roll forward until after the re-set moratorium, then it expires.
- scheduler.timeMillis = triggerTime + 5000000;
- assertEquals(triggerTime, scheduler.getNextTimeMillis(options));
- assertEquals(beforeRollback, scheduler.getLastAttemptTimeMillis());
- assertEquals(beforeRollback, scheduler.getLastSuccessTimeMillis());
- }
-}
diff --git a/common/tools/make-iana-tld-pattern.py b/common/tools/make-iana-tld-pattern.py
deleted file mode 100755
index de81c58..0000000
--- a/common/tools/make-iana-tld-pattern.py
+++ /dev/null
@@ -1,144 +0,0 @@
-#!/usr/bin/env python
-
-from urllib2 import urlopen
-
-TLD_PREFIX = r"""
- /**
- * Regular expression to match all IANA top-level domains.
- * List accurate as of 2010/02/05. List taken from:
- * http://data.iana.org/TLD/tlds-alpha-by-domain.txt
- * This pattern is auto-generated by frameworks/base/common/tools/make-iana-tld-pattern.py
- */
- public static final String TOP_LEVEL_DOMAIN_STR =
-"""
-TLD_SUFFIX = '";'
-
-URL_PREFIX = r"""
- /**
- * Regular expression to match all IANA top-level domains for WEB_URL.
- * List accurate as of 2010/02/05. List taken from:
- * http://data.iana.org/TLD/tlds-alpha-by-domain.txt
- * This pattern is auto-generated by frameworks/base/common/tools/make-iana-tld-pattern.py
- */
- public static final String TOP_LEVEL_DOMAIN_STR_FOR_WEB_URL =
- "(?:"
-"""
-
-URL_SUFFIX = ';'
-
-class Bucket:
- def __init__(self, baseLetter):
- self.base=baseLetter
- self.words=[]
- self.letters=[]
-
- def dump(self, isWebUrl=False, isFirst=False, isLast=False):
- if (len(self.words) == 0) and (len(self.letters) == 0):
- return ''
-
- self.words.sort()
- self.letters.sort()
-
- output = ' ';
-
- if isFirst:
- if isWebUrl:
- output += '+ "'
- else:
- output += '"('
- else:
- output += '+ "|'
-
- if len(self.words) != 0:
- output += '('
-
- if isWebUrl:
- output += '?:'
-
- firstWord = 1
- for word in self.words:
- if firstWord == 0:
- output += '|'
- firstWord = 0
- for letter in word:
- if letter == '-':
- output += '\\\\' # escape the '-' character.
- output += letter
-
- if len(self.words) > 0 and len(self.letters) > 0:
- output += '|'
-
- if len(self.letters) == 1:
- output += '%c%c' % (self.base, self.letters[0])
- elif len(self.letters) > 0:
- output += '%c[' % self.base
-
- for letter in self.letters:
- output += letter
-
- output += ']'
-
- if len(self.words) != 0:
- output += ')'
-
- if not isLast:
- output += '"'
- output += '\n'
-
- return output;
-
- def add(self, line):
- length = len(line)
-
- if line.startswith('#') or (length == 0):
- return;
-
- if length == 2:
- self.letters.append(line[1:2])
- else:
- self.words.append(line)
-
-def getBucket(buckets, line):
- letter = line[0]
- bucket = buckets.get(letter)
-
- if bucket is None:
- bucket = Bucket(letter)
- buckets[letter] = bucket
-
- return bucket
-
-def makePattern(prefix, suffix, buckets, isWebUrl=False):
- output = prefix
-
- output += getBucket(buckets, 'a').dump(isFirst=True, isWebUrl=isWebUrl)
-
- for letter in range(ord('b'), ord('z')):
- output += getBucket(buckets, chr(letter)).dump(isWebUrl=isWebUrl)
-
- output += getBucket(buckets, 'z').dump(isLast=True, isWebUrl=isWebUrl)
-
- if isWebUrl:
- output += '))"'
- else:
- output += ')'
-
- output += suffix
-
- print output
-
-if __name__ == "__main__":
- f = urlopen('http://data.iana.org/TLD/tlds-alpha-by-domain.txt')
- domains = f.readlines()
- f.close()
-
- buckets = {}
-
- for domain in domains:
- domain = domain.lower()
-
- if len(domain) > 0:
- getBucket(buckets, domain[0]).add(domain.strip())
-
- makePattern(TLD_PREFIX, TLD_SUFFIX, buckets, isWebUrl=False)
- makePattern(URL_PREFIX, URL_SUFFIX, buckets, isWebUrl=True)
diff --git a/core/java/android/app/ApplicationErrorReport.java b/core/java/android/app/ApplicationErrorReport.java
index 57a23ae..9834c4c 100644
--- a/core/java/android/app/ApplicationErrorReport.java
+++ b/core/java/android/app/ApplicationErrorReport.java
@@ -254,6 +254,10 @@
/**
* Describes an application crash.
+ *
+ * <p>This is also used to marshal around stack traces of ANRs and
+ * StrictMode violations which aren't necessarily crashes, but have
+ * a lot in common.
*/
public static class CrashInfo {
/**
@@ -292,6 +296,12 @@
public String stackTrace;
/**
+ * For StrictMode violations, the wall time duration of the
+ * violation, when known.
+ */
+ public long durationMillis = -1;
+
+ /**
* Create an uninitialized instance of CrashInfo.
*/
public CrashInfo() {
@@ -334,6 +344,7 @@
throwMethodName = in.readString();
throwLineNumber = in.readInt();
stackTrace = in.readString();
+ durationMillis = in.readLong();
}
/**
@@ -347,6 +358,7 @@
dest.writeString(throwMethodName);
dest.writeInt(throwLineNumber);
dest.writeString(stackTrace);
+ dest.writeLong(durationMillis);
}
/**
@@ -360,6 +372,9 @@
pw.println(prefix + "throwMethodName: " + throwMethodName);
pw.println(prefix + "throwLineNumber: " + throwLineNumber);
pw.println(prefix + "stackTrace: " + stackTrace);
+ if (durationMillis != -1) {
+ pw.println(prefix + "durationMillis: " + durationMillis);
+ }
}
}
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 9d1a634..fdd3573 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -179,10 +179,22 @@
*/
public static final int ECLAIR_MR1 = 7;
+ /**
+ * June 2010: Android 2.2
+ */
public static final int FROYO = 8;
- public static final int KRAKEN = CUR_DEVELOPMENT;
-
+ /**
+ * Next version of Android.
+ *
+ * <p>Applications targeting this or a later release will get these
+ * new changes in behavior:</p>
+ * <ul>
+ * <li> The status bar is now dark. Targeting this version allows
+ * the platform to perform performing compatibility on status bar
+ * graphics to ensure they look okay on a dark background.
+ * </ul>
+ */
public static final int GINGERBREAD = CUR_DEVELOPMENT;
}
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index c0ae263..9b18719 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -187,6 +187,7 @@
// Not _really_ a Crash, but we use the same data structure...
ApplicationErrorReport.CrashInfo crashInfo =
new ApplicationErrorReport.CrashInfo(violation);
+ crashInfo.durationMillis = durationMillis;
// Not perfect, but fast and good enough for dup suppression.
Integer crashFingerprint = crashInfo.stackTrace.hashCode();
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 8beceec..d1a0f75 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -724,6 +724,12 @@
}
public void setFormat(int format) {
+
+ // for backward compatibility reason, OPAQUE always
+ // means 565 for SurfaceView
+ if (format == PixelFormat.OPAQUE)
+ format = PixelFormat.RGB_565;
+
mRequestedFormat = format;
if (mWindow != null) {
updateWindow(false);
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 0aa1fde..adceeb2 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -685,7 +685,7 @@
/** Adjustment option for {@link #softInputMode}: set to allow the
* window to be resized when an input
* method is shown, so that its contents are not covered by the input
- * method. This can <em>not<em> be combined with
+ * method. This can <em>not</em> be combined with
* {@link #SOFT_INPUT_ADJUST_PAN}; if
* neither of these are set, then the system will try to pick one or
* the other depending on the contents of the window.
@@ -696,7 +696,7 @@
* pan when an input method is
* shown, so it doesn't need to deal with resizing but just panned
* by the framework to ensure the current input focus is visible. This
- * can <em>not<em> be combined with {@link #SOFT_INPUT_ADJUST_RESIZE}; if
+ * can <em>not</em> be combined with {@link #SOFT_INPUT_ADJUST_RESIZE}; if
* neither of these are set, then the system will try to pick one or
* the other depending on the contents of the window.
*/
diff --git a/core/res/res/drawable-hdpi/presence_audio_away.png b/core/res/res/drawable-hdpi/presence_audio_away.png
new file mode 100644
index 0000000..f18b6c9
--- /dev/null
+++ b/core/res/res/drawable-hdpi/presence_audio_away.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/presence_audio_busy.png b/core/res/res/drawable-hdpi/presence_audio_busy.png
new file mode 100644
index 0000000..ae7b983
--- /dev/null
+++ b/core/res/res/drawable-hdpi/presence_audio_busy.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/presence_audio_online.png b/core/res/res/drawable-hdpi/presence_audio_online.png
new file mode 100644
index 0000000..15e4513
--- /dev/null
+++ b/core/res/res/drawable-hdpi/presence_audio_online.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/presence_video_away.png b/core/res/res/drawable-hdpi/presence_video_away.png
new file mode 100644
index 0000000..f18b6c9
--- /dev/null
+++ b/core/res/res/drawable-hdpi/presence_video_away.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/presence_video_busy.png b/core/res/res/drawable-hdpi/presence_video_busy.png
new file mode 100644
index 0000000..ae7b983
--- /dev/null
+++ b/core/res/res/drawable-hdpi/presence_video_busy.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/presence_video_online.png b/core/res/res/drawable-hdpi/presence_video_online.png
new file mode 100644
index 0000000..15e4513
--- /dev/null
+++ b/core/res/res/drawable-hdpi/presence_video_online.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/presence_audio_away.png b/core/res/res/drawable-mdpi/presence_audio_away.png
new file mode 100644
index 0000000..f67e64e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/presence_audio_away.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/presence_audio_busy.png b/core/res/res/drawable-mdpi/presence_audio_busy.png
new file mode 100644
index 0000000..0ad991b
--- /dev/null
+++ b/core/res/res/drawable-mdpi/presence_audio_busy.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/presence_audio_online.png b/core/res/res/drawable-mdpi/presence_audio_online.png
new file mode 100644
index 0000000..6cc3d1a
--- /dev/null
+++ b/core/res/res/drawable-mdpi/presence_audio_online.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/presence_video_away.png b/core/res/res/drawable-mdpi/presence_video_away.png
new file mode 100644
index 0000000..f67e64e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/presence_video_away.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/presence_video_busy.png b/core/res/res/drawable-mdpi/presence_video_busy.png
new file mode 100644
index 0000000..0ad991b
--- /dev/null
+++ b/core/res/res/drawable-mdpi/presence_video_busy.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/presence_video_online.png b/core/res/res/drawable-mdpi/presence_video_online.png
new file mode 100644
index 0000000..6cc3d1a
--- /dev/null
+++ b/core/res/res/drawable-mdpi/presence_video_online.png
Binary files differ
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 1932771..27cb763 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1250,7 +1250,16 @@
<public-padding type="id" name="kraken_resource_pad" end="0x01020040" />
<public-padding type="anim" name="kraken_resource_pad" end="0x010a0020" />
+
+ <!-- presence drawables for videochat or audiochat capable contacts -->
+ <public type="drawable" name="presence_video_away" id="0x010800ac" />
+ <public type="drawable" name="presence_video_busy" id="0x010800ad" />
+ <public type="drawable" name="presence_video_online" id="0x010800ae" />
+ <public type="drawable" name="presence_audio_away" id="0x010800af" />
+ <public type="drawable" name="presence_audio_busy" id="0x010800b0" />
+ <public type="drawable" name="presence_audio_online" id="0x010800b1" />
<public-padding type="drawable" name="kraken_resource_pad" end="0x01080100" />
+
<public-padding type="style" name="kraken_resource_pad" end="0x01030090" />
<public-padding type="string" name="kraken_resource_pad" end="0x01040020" />
<public-padding type="integer" name="kraken_resource_pad" end="0x010e0010" />
diff --git a/docs/html/guide/topics/resources/providing-resources.jd b/docs/html/guide/topics/resources/providing-resources.jd
index 0f3d389..6d98385 100644
--- a/docs/html/guide/topics/resources/providing-resources.jd
+++ b/docs/html/guide/topics/resources/providing-resources.jd
@@ -9,6 +9,7 @@
<ul>
<li>Different types of resources belong in different subdirectories of {@code res/}</li>
<li>Alternative resources provide configuration-specific resource files</li>
+ <li>Always include default resources so your app does not depend on specific configurations</li>
</ul>
<h2>In this document</h2>
<ol>
@@ -19,7 +20,9 @@
<li><a href="#AliasResources">Creating alias resources</a></li>
</ol>
</li>
+ <li><a href="#Compatibility">Providing the Best Device Compatibility with Resources</a></li>
<li><a href="#BestMatch">How Android Finds the Best-matching Resource</a></li>
+ <li><a href="#KnownIssues">Known Issues</a></li>
</ol>
<h2>See also</h2>
@@ -35,13 +38,14 @@
<p>You should always externalize application resources such as images and strings from your
code, so that you can maintain them independently. You can also provide alternative resources for
specific device configurations, by grouping them in specially-named resource directories. Android
-will then automatically apply the appropriate resource based on the current configuration. For
+then applies the appropriate resource based on the current configuration. For
instance, you might want to provide a different UI layout depending on the screen size.</p>
-<p>Once you save your resources external to your application code, you can access them
+<p>Once you externalize your application resources, you can access them
using resource IDs that are generated in your project's {@code R} class. How to use
resources in your application is discussed in <a href="accessing-resources.html">Accessing
-Resources</a>.</p>
+Resources</a>. This document shows you how to group your resources in your Android project and
+provide alternative resources for specific device configurations.</p>
<h2 id="ResourceTypes">Grouping Resource Types</h2>
@@ -63,9 +67,9 @@
strings.xml </span>
</pre>
-<p>The {@code res/} directory contains all the resources (in subdirectories): an image resource, two
-layout resources, and a string resource file. The resource directory names are important and are
-described in table 1.</p>
+<p>As you can see in this example, the {@code res/} directory contains all the resources (in
+subdirectories): an image resource, two layout resources, and a string resource file. The resource
+directory names are important and are described in table 1.</p>
<p class="table-caption" id="table1"><strong>Table 1.</strong> Resource directories
supported inside project {@code res/} directory.</p>
@@ -96,9 +100,9 @@
<li>Bitmap files</li>
<li>Nine-Patches (re-sizable bitmaps)</li>
<li>State lists</li>
- <li>Color drawables</li>
<li>Shapes</li>
<li>Animation drawables</li>
+ <li>Other drawables</li>
</ul>
<p>See <a href="drawable-resource.html">Drawable Resources</a>.</p>
</td>
@@ -168,16 +172,21 @@
</tr>
</table>
-<p class="note"><strong>Note:</strong> You should never save resource files directly inside the
-{@code res/} directory.</p>
+<p class="caution"><strong>Caution:</strong> Never save resource files directly inside the
+{@code res/} directory—it will cause a compiler error.</p>
<p>For more information about certain types of resources, see the <a
href="available-resources.html">Resource Types</a> documentation.</p>
-<p>How to access resources in the {@code res/} subdirectories is discussed in <a
-href="accessing-resources.html">Accessing Resources</a>.
-</p>
-
+<p>The resources that you save in the subdirectories defined in table 1 are your "default"
+resources. That is, these resources define the default design and content for your application.
+However, different types of Android-powered devices might call for different types of resources.
+For example, if a device has a larger than normal screen, then you should provide
+different layout resources that take advantage of the extra screen space. Or, if a device has a
+different language setting, then you should provide different string resources that translate the
+text in your user interface. To provide these different resources for different device
+configurations, you need to provide "alternative" resources, in addition to your default
+resources.</p>
<h2 id="AlternativeResources">Providing Alternative Resources</h2>
@@ -192,8 +201,8 @@
<p>Almost every application should provide alternative resources to support specific device
configurations. For instance, you should include alternative drawable resources for different
screen densities and alternative string resources for different languages. At runtime, Android
-automatically detects the current device configuration and loads the appropriate
-resources.</p>
+detects the current device configuration and loads the appropriate
+resources for your application.</p>
<p>To specify configuration-specific alternatives for a set of resources:</p>
<ol>
@@ -201,15 +210,15 @@
<em><resources_name></em>-<em><config_qualifier></em>}.
<ul>
<li><em>{@code <resources_name>}</em> is the directory name of the corresponding default
-resources.</li>
+resources (defined in table 1).</li>
<li><em>{@code <config_qualifier>}</em> is a name that specifies a configuration
-for which these resources are to be used.</li>
+for which these resources are to be used (defined in table 2).</li>
</ul>
<p>You can append more than one <em>{@code <config_qualifier>}</em>. Separate each
one with a dash.</p>
</li>
- <li>Save your alternative resources in this new directory. The resource files must be named
-exactly the same as the default resource files.</li>
+ <li>Save the respective alternative resources in this new directory. The resource files must be
+named exactly the same as the default resource files.</li>
</ol>
<p>For example, here are some default and alternative resources:</p>
@@ -225,18 +234,24 @@
</pre>
<p>The {@code hdpi} qualifier indicates that the resources in that directory are for devices with a
-high-density screen. While the images in each drawable directory are sized for a specific screen
-density, the filenames are
+high-density screen. The images in each of these drawable directories are sized for a specific
+screen density, but the filenames are exactly
the same. This way, the resource ID that you use to reference the {@code icon.png} or {@code
background.png} image is always the same, but Android selects the
-version of that drawable that best matches the current device configuration.</p>
+version of each resource that best matches the current device, by comparing the device
+configuration information with the qualifiers in the alternative resource directory name.</p>
<p>Android supports several configuration qualifiers and you can
add multiple qualifiers to one directory name, by separating each qualifier with a dash. Table 2
lists the valid configuration qualifiers, in order of precedence—if you use multiple
-qualifiers, they must be added to the directory name in the order they are listed in the
-table.</p>
+qualifiers for one resource directory, they must be added to the directory name in the order they
+are listed in the table.</p>
+<p class="note"><strong>Note:</strong> Some resource qualifiers were added after Android 1.0, so not
+all versions of Android support all the qualifiers listed in table 2. New qualifiers
+indicate the version in which they were added. To avoid any issues, always include a set of default
+resources for resources that your application uses. For more information, see the section about <a
+href="#Compatibility">Providing the Best Device Compatibility with Resources</a>.</p>
<p class="table-caption" id="table2"><strong>Table 2.</strong> Alternative resource qualifier
names.</p>
@@ -246,7 +261,7 @@
<th>Values</th>
<th>Description</th>
</tr>
- <tr>
+ <tr id="MccQualifier">
<td>MCC and MNC</td>
<td>Examples:<br/>
<code>mcc310</code><br/>
@@ -272,7 +287,7 @@
and mobile network code, respectively.</p>
</td>
</tr>
- <tr>
+ <tr id="LocaleQualifier">
<td>Language and region</td>
<td>Examples:<br/>
<code>en</code><br/>
@@ -297,12 +312,12 @@
href="runtime-changes.html">Handling Runtime Changes</a> for information about
how this can affect your application during runtime.</p>
<p>See <a href="localization.html">Localization</a> for a complete guide to localizing
-your application for other langauges.</p>
+your application for other languages.</p>
<p>Also see the {@link android.content.res.Configuration#locale} configuration field, which
indicates the current locale.</p>
</td>
</tr>
- <tr>
+ <tr id="ScreenSizeQualifier">
<td>Screen size</td>
<td>
<code>small</code><br/>
@@ -326,6 +341,7 @@
available space in both width and height than an HVGA display.
Examples are VGA and WVGA medium density screens.</li>
</ul>
+ <p><em>Added in API Level 4.</em></p>
<p>See <a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
Screens</a> for more information.</p>
<p>Also see the {@link android.content.res.Configuration#screenLayout} configuration field,
@@ -333,7 +349,7 @@
or large.</p>
</td>
</tr>
- <tr>
+ <tr id="ScreenLongQualifier">
<td>Wider/taller screens</td>
<td>
<code>long</code><br/>
@@ -344,13 +360,14 @@
<li>{@code long}: Long screens, such as WQVGA, WVGA, FWVGA</li>
<li>{@code notlong}: Not long screens, such as QVGA, HVGA, and VGA</li>
</ul>
+ <p><em>Added in API Level 4.</em></p>
<p>This is based purely on the aspect ratio of the screen (a "long" screen is wider). This
is not related to the screen orientation.</p>
<p>Also see the {@link android.content.res.Configuration#screenLayout} configuration field,
which indicates whether the screen is long.</p>
</td>
</tr>
- <tr>
+ <tr id="OrientationQualifier">
<td>Screen orientation</td>
<td>
<code>port</code><br/>
@@ -370,7 +387,7 @@
which indicates the current device orientation.</p>
</td>
</tr>
- <tr>
+ <tr id="DockQualifier">
<td>Dock mode</td>
<td>
<code>car</code><br/>
@@ -383,12 +400,12 @@
</ul>
<p><em>Added in API Level 8.</em></p>
<p>This can change during the life of your application if the user places the device in a
-dock. You can eneable or disable this mode using {@link
+dock. You can enable or disable this mode using {@link
android.app.UiModeManager}. See <a href="runtime-changes.html">Handling Runtime Changes</a> for
information about how this affects your application during runtime.</p>
</td>
</tr>
- <tr>
+ <tr id="NightQualifier">
<td>Night mode</td>
<td>
<code>night</code><br/>
@@ -401,13 +418,13 @@
</ul>
<p><em>Added in API Level 8.</em></p>
<p>This can change during the life of your application if night mode is left in
-auto mode (default), in which case the mode changes based on the time of day. You can eneable
+auto mode (default), in which case the mode changes based on the time of day. You can enable
or disable this mode using {@link android.app.UiModeManager}. See <a
href="runtime-changes.html">Handling Runtime Changes</a> for information about how this affects your
application during runtime.</p>
</td>
</tr>
- <tr>
+ <tr id="DensityQualifier">
<td>Screen pixel density (dpi)</td>
<td>
<code>ldpi</code><br/>
@@ -424,6 +441,7 @@
<li>{@code nodpi}: This can be used for bitmap resources that you do not want to be scaled
to match the device density.</li>
</ul>
+ <p><em>Added in API Level 4.</em></p>
<p>There is thus a 4:3 scaling factor between each density, so a 9x9 bitmap
in ldpi is 12x12 in mdpi and 16x16 in hdpi.</p>
<p>When Android selects which resource files to use,
@@ -439,7 +457,7 @@
your bitmaps.</p>
</td>
</tr>
- <tr>
+ <tr id="TouchscreenQualifier">
<td>Touchscreen type</td>
<td>
<code>notouch</code><br/>
@@ -457,7 +475,7 @@
which indicates the type of touchscreen on the device.</p>
</td>
</tr>
- <tr>
+ <tr id="KeyboardAvailQualifier">
<td>Keyboard availability</td>
<td>
<code>keysexposed</code><br/>
@@ -487,7 +505,7 @@
keyboard and and the visibility of any kind of keyboard (including software), respectively.</p>
</td>
</tr>
- <tr>
+ <tr id="ImeQualifier">
<td>Primary text input method</td>
<td>
<code>nokeys</code><br/>
@@ -497,7 +515,8 @@
<td>
<ul class="nolist">
<li>{@code nokeys}: Device has no hardware keys for text input.</li>
- <li>{@code qwert}: Device has a hardware qwerty keyboard, whether it's visible to the user
+ <li>{@code qwerty}: Device has a hardware qwerty keyboard, whether it's visible to the
+user
or not.</li>
<li>{@code 12key}: Device has a hardware 12-key keyboard, whether it's visible to the user
or not.</li>
@@ -506,7 +525,7 @@
which indicates the primary text input method available.</p>
</td>
</tr>
- <tr>
+ <tr id="NavAvailQualifier">
<td>Navigation key availability</td>
<td>
<code>navexposed</code><br/>
@@ -525,7 +544,7 @@
field, which indicates whether navigation keys are hidden.</p>
</td>
</tr>
- <tr>
+ <tr id="TouchQualifier">
<td>Primary non-touch navigation method</td>
<td>
<code>nonav</code><br/>
@@ -560,19 +579,22 @@
</td>
</tr>
-->
- <tr>
- <td>API Level</td>
+ <tr id="VersionQualifier">
+ <td>System Version (API Level)</td>
<td>Examples:<br/>
+ <code>v3</code><br/>
<code>v4</code><br/>
- <code>v5</code><br/>
- <code>v6</code><br/>
<code>v7</code><br/>
etc.</td>
<td>
- <p>The API Level supported by the device, for example <code>v1</code> for API Level 1
-(Android 1.0) or <code>v5</code> for API Level 5 (Android 2.0). See the <a
+ <p>The API Level supported by the device. For example, <code>v1</code> for API Level
+1 (devices with Android 1.0 or higher) and <code>v4</code> for API Level 4 (devices with Android
+1.6 or higher). See the <a
href="{@docRoot}guide/appendix/api-levels.html">Android API Levels</a> document for more information
about these values.</p>
+ <p class="caution"><strong>Caution:</strong> Android 1.5 and 1.6 only match resources
+with this qualifier when it exactly matches the system version. See the section below about <a
+href="#KnownIssues">Known Issues</a> for more information.</p>
</td>
</tr>
</table>
@@ -702,6 +724,54 @@
+<h2 id="Compatibility">Providing the Best Device Compatibility with Resources</h2>
+
+<p>In order for your application to support multiple device configurations, it's very important that
+you always provide default resources for each type of resource that your application uses.</p>
+
+<p>For example, if your application supports several languages, always include a {@code
+values/} directory (in which your strings are saved) <em>without</em> a <a
+href="#LocalQualifier">language and region qualifier</a>. If you instead put all your string files
+in directories that have a language and region qualifier, then your application will crash when run
+on a device set to a language that your strings do not support. But, as long as you provide default
+{@code values/} resources, then your application will run properly (even if the user doesn't
+understand that language—it's better than crashing).</p>
+
+<p>Likewise, if you provide different layout resources based on the screen orientation, you should
+pick one orientation as your default. For example, instead of providing layout resources in {@code
+layout-land/} for landscape and {@code layout-port/} for portrait, leave one as the default, such as
+{@code layout/} for landscape and {@code layout-port/} for portrait.</p>
+
+<p>Providing default resources is important not only because your application might run on a
+configuration you had not anticipated, but also because new versions of Android sometimes add
+resource qualifiers that older versions do not support. If you use a new resource qualifier,
+but maintain code compatibility with older versions of Android, then when an older version of
+Android runs your application, it will crash if you do not provide default resources, because it
+cannot use the resources named with the new qualifier. For example, if your <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
+minSdkVersion}</a> is set to 4, and you qualify all of your drawable resources using <a
+href="NightQualifier">night mode</a> ({@code night} or {@code notnight}, which were added in API
+Level 8), then an API Level 4 device cannot access your drawable resources and will crash. In this
+case, you probably want {@code notnight} to be your default resources, so you should exclude that
+qualifier so your drawable resources are in either {@code drawable/} or {@code drawable-night/}.</p>
+
+<p>The bottom line is: For every type of resource your application uses,
+provide a set of default resources that allow your application to perform well, then create
+variations of those resources for specific device configurations.</p>
+
+<p>There is one exception to this rule: If your application's <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a> is 4 or
+greater, you <em>do not</em> need default drawable resources when you provide alternative drawable
+resources with the <a href="#DensityQualifier">screen density</a> qualifier. Even without default
+drawable resources, Android can find the best match among the alternative screen densities and scale
+the bitmaps as necessary. However, for the best experience on all types of devices, you should
+provide alternative drawables for all three types of density. (If your <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a> is
+<em>less than</em> 4, see the section below about <a href="#KnownIssues">known issues</a> for
+information about how to support multiple screen densities.)</p>
+
+
+
<h2 id="BestMatch">How Android Finds the Best-matching Resource</h2>
@@ -820,3 +890,82 @@
href="accessing-resources.html">Accessing Resources</a>.</p>
+
+
+<h2 id="KnownIssues">Known Issues</h2>
+
+<p>The following are known issues in terms of how Android finds the best-matching resource on
+certain versions of Android.</p>
+
+<h3>Android 1.5 (and lower)</h3>
+
+<h4>Density and screen size qualifiers are not supported</h4>
+
+<p>Android 1.5 (and lower) does not support the following resource qualifers:</p>
+<dl>
+ <dt><a href="#DensityQualifier">Density</a></dt>
+ <dd>{@code ldpi}, {@code mdpi}, {@code ldpi}, and {@code nodpi}</dd>
+ <dt><a href="#ScreenSizeQualifier">Screen size</a></dt>
+ <dd>{@code small}, {@code normal}, and {@code large}</dd>
+ <dt><a href="#ScreenLongQualifier">Screen length</a></dt>
+ <dd>{@code long} and {@code notlong}</dd>
+</dl>
+
+<p>These resource qualifiers were introduced in Android 1.6, so Android 1.5 (API Level 3) and lower
+does not support them. If your application supports Android 1.5 and includes drawable resources for
+each density type ({@code drawable-ldpi/}, {@code drawable-mdpi/}, and {@code drawable-ldpi/}), then
+an Android 1.5 device might use any one of them, because it doesn't support the density qualifier,
+will ignore it, and will use which ever otherwise-matching drawable resource it finds first. This
+caveat applies the same to screen size and screen length resources.<p>
+
+<p><b>The fix:</b> Ensure that your <a href="{@docRoot}sdk/tools-notes.html">SDK Tools</a> version
+is r6 or greater and provide default drawable resources. For example, to support Android 1.5
+while providing resources for all screen densities, include a set of drawable resources that does
+not use the screen density qualifier. In fact, because all Android 1.5 devices have a medium-density
+screen, you can remove the {@code mdpi} qualifer and put all medium density images in {@code
+drawable/} (instead of {@code drawable-mdpi/}). For the screen size, put your {@code normal} size
+resources in the default resource directory, and for the screen length, put your {@code notlong}
+resources in the default resource directory (because all Android 1.5 devices have medium-density,
+normal, not-long screens).</p>
+
+<p>You need SDK Tools, Revision 6 (or greater), because it includes a new packaging tool that
+automatically applies an appropriate <a href="#VersionQualifier">version qualifier</a> to any
+resource directory named with a qualifier that did not exist in Android 1.0. For example, because
+the density qualifier was introduced in Android 1.6 (API Level 4), when the packaging tool
+encounters a resource directory using the density qualifier, it adds {@code v4} to the directory
+name to ensure that older versions do not use those resources (only API Level 4 and higher support
+that qualifier). Thus, by putting your medium-density resources in a directory <em>without</em> the
+{@code mdpi} qualifier, they are still accessible by Android 1.5, and any device that supports the
+density qualifer and has a medium-density screen also uses these resources because they are the best
+match for the device (instead of using the {@code ldpi} or {@code hdpi} resources).</p>
+
+<p class="note"><strong>Note:</strong> Later versions of Android, such as API Level 8,
+introduce other resource qualifiers that older version do not support. To provide the best
+compatibility, you should always include a set of default resources for each type of resource
+that your application uses. See the section about <a href="#Compatibility">Providing the Best Device
+Compatibility with Resources</a> for more information.</p>
+
+
+
+<h3>Android 1.5 and 1.6</h3>
+
+<h4>Version qualifier performs exact match, instead of best match</h4>
+
+<p>The correct behavior is for the system to match resources marked with a <a
+href="#VersionQualifier">version qualifier</a> equal
+to or less than the system version on the device, but on Android 1.5 and 1.6, (API Level 3 and 4),
+there is a bug that causes the system to match resources marked with the version qualifier
+only when it exactly matches the version on the device.</p>
+
+<p><b>The fix:</b> To provide version-specific resources, abide by this behavior. However, because
+this bug is fixed in versions of Android available after 1.6, if
+you need to differentiate resources between Android 1.5, 1.6, and later versions, then you only need
+to apply the version qualifier to the 1.6 resources and one to match all later versions. Thus, this
+is effectively a non-issue.</p>
+
+<p>For example, if you want drawable resources that are different on each Android 1.5, 1.6,
+and 2.0.1 (and later), create three drawable directories: {@code drawable/} (for 1.5 and lower),
+{@code drawable-v4} (for 1.6), and {@code drawable-v6} (for 2.0.1 and later—version 2.0, v5,
+is no longer available).</p>
+
+
diff --git a/libs/ui/tests/Android.mk b/libs/ui/tests/Android.mk
index 018f18d..1ff896b 100644
--- a/libs/ui/tests/Android.mk
+++ b/libs/ui/tests/Android.mk
@@ -5,7 +5,7 @@
test_src_files := \
InputDispatcher_test.cpp
-LOCAL_SHARED_LIBRARIES := \
+shared_libraries := \
libcutils \
libutils \
libEGL \
@@ -16,21 +16,26 @@
libui \
libstlport
-LOCAL_STATIC_LIBRARIES := \
+static_libraries := \
libgtest \
libgtest_main
-LOCAL_C_INCLUDES := \
+c_includes := \
bionic \
bionic/libstdc++/include \
external/gtest/include \
external/stlport/stlport
-LOCAL_MODULE_TAGS := eng tests
+module_tags := eng tests
$(foreach file,$(test_src_files), \
+ $(eval include $(CLEAR_VARS)) \
+ $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
+ $(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \
+ $(eval LOCAL_C_INCLUDES := $(c_includes)) \
$(eval LOCAL_SRC_FILES := $(file)) \
$(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
+ $(eval LOCAL_MODULE_TAGS := $(module_tags)) \
$(eval include $(BUILD_EXECUTABLE)) \
)
diff --git a/libs/utils/tests/Android.mk b/libs/utils/tests/Android.mk
index 45e8061..92ebfd7c 100644
--- a/libs/utils/tests/Android.mk
+++ b/libs/utils/tests/Android.mk
@@ -5,18 +5,18 @@
test_src_files := \
PollLoop_test.cpp
-LOCAL_SHARED_LIBRARIES := \
+shared_libraries := \
libz \
liblog \
libcutils \
libutils \
libstlport
-LOCAL_STATIC_LIBRARIES := \
+static_libraries := \
libgtest \
libgtest_main
-LOCAL_C_INCLUDES := \
+c_includes := \
external/zlib \
external/icu4c/common \
bionic \
@@ -24,10 +24,15 @@
external/gtest/include \
external/stlport/stlport
-LOCAL_MODULE_TAGS := eng tests
+module_tags := eng tests
$(foreach file,$(test_src_files), \
+ $(eval include $(CLEAR_VARS)) \
+ $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
+ $(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \
+ $(eval LOCAL_C_INCLUDES := $(c_includes)) \
$(eval LOCAL_SRC_FILES := $(file)) \
$(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
+ $(eval LOCAL_MODULE_TAGS := $(module_tags)) \
$(eval include $(BUILD_EXECUTABLE)) \
)
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 6be41b4..5a01d79 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -347,7 +347,7 @@
quirks |= kRequiresAllocateBufferOnInputPorts;
quirks |= kRequiresAllocateBufferOnOutputPorts;
- if (!strncmp(componentName, "OMX.TI.video.encoder", 20)) {
+ if (!strncmp(componentName, "OMX.TI.Video.encoder", 20)) {
quirks |= kAvoidMemcopyInputRecordingFrames;
}
}
diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h
index ea131e8..c99da59 100644
--- a/media/libstagefright/include/OMX.h
+++ b/media/libstagefright/include/OMX.h
@@ -102,7 +102,7 @@
OMX_IN OMX_U32 nData1,
OMX_IN OMX_U32 nData2,
OMX_IN OMX_PTR pEventData);
-
+
OMX_ERRORTYPE OnEmptyBufferDone(
node_id node, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer);
@@ -115,20 +115,19 @@
virtual ~OMX();
private:
- Mutex mLock;
-
- OMXMaster *mMaster;
-
struct CallbackDispatcher;
- sp<CallbackDispatcher> mDispatcher;
+ Mutex mLock;
+ OMXMaster *mMaster;
int32_t mNodeCounter;
KeyedVector<wp<IBinder>, OMXNodeInstance *> mLiveNodes;
KeyedVector<node_id, OMXNodeInstance *> mNodeIDToInstance;
+ KeyedVector<node_id, sp<CallbackDispatcher> > mDispatchers;
node_id makeNodeID(OMXNodeInstance *instance);
OMXNodeInstance *findInstance(node_id node);
+ sp<CallbackDispatcher> findDispatcher(node_id node);
void invalidateNodeID_l(node_id node);
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index 132e31b..ad5b0f9 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -43,7 +43,7 @@
////////////////////////////////////////////////////////////////////////////////
struct OMX::CallbackDispatcher : public RefBase {
- CallbackDispatcher(OMX *owner);
+ CallbackDispatcher(OMXNodeInstance *owner);
void post(const omx_message &msg);
@@ -53,7 +53,7 @@
private:
Mutex mLock;
- OMX *mOwner;
+ OMXNodeInstance *mOwner;
bool mDone;
Condition mQueueChanged;
List<omx_message> mQueue;
@@ -69,7 +69,7 @@
CallbackDispatcher &operator=(const CallbackDispatcher &);
};
-OMX::CallbackDispatcher::CallbackDispatcher(OMX *owner)
+OMX::CallbackDispatcher::CallbackDispatcher(OMXNodeInstance *owner)
: mOwner(owner),
mDone(false) {
pthread_attr_t attr;
@@ -101,12 +101,11 @@
}
void OMX::CallbackDispatcher::dispatch(const omx_message &msg) {
- OMXNodeInstance *instance = mOwner->findInstance(msg.node);
- if (instance == NULL) {
+ if (mOwner == NULL) {
LOGV("Would have dispatched a message to a node that's already gone.");
return;
}
- instance->onMessage(msg);
+ mOwner->onMessage(msg);
}
// static
@@ -145,7 +144,6 @@
OMX::OMX()
: mMaster(new OMXMaster),
- mDispatcher(new CallbackDispatcher(this)),
mNodeCounter(0) {
}
@@ -226,6 +224,7 @@
}
*node = makeNodeID(instance);
+ mDispatchers.add(*node, new CallbackDispatcher(instance));
instance->setHandle(*node, handle);
@@ -341,7 +340,7 @@
msg.u.event_data.data1 = nData1;
msg.u.event_data.data2 = nData2;
- mDispatcher->post(msg);
+ findDispatcher(node)->post(msg);
return OMX_ErrorNone;
}
@@ -355,7 +354,7 @@
msg.node = node;
msg.u.buffer_data.buffer = pBuffer;
- mDispatcher->post(msg);
+ findDispatcher(node)->post(msg);
return OMX_ErrorNone;
}
@@ -375,7 +374,7 @@
msg.u.extended_buffer_data.platform_private = pBuffer->pPlatformPrivate;
msg.u.extended_buffer_data.data_ptr = pBuffer->pBuffer;
- mDispatcher->post(msg);
+ findDispatcher(node)->post(msg);
return OMX_ErrorNone;
}
@@ -397,6 +396,14 @@
return index < 0 ? NULL : mNodeIDToInstance.valueAt(index);
}
+sp<OMX::CallbackDispatcher> OMX::findDispatcher(node_id node) {
+ Mutex::Autolock autoLock(mLock);
+
+ ssize_t index = mDispatchers.indexOfKey(node);
+
+ return index < 0 ? NULL : mDispatchers.valueAt(index);
+}
+
void OMX::invalidateNodeID(node_id node) {
Mutex::Autolock autoLock(mLock);
invalidateNodeID_l(node);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index e93f7ff..ec209eda 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -648,6 +648,15 @@
= new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
/**
+ * Fingerprints (String.hashCode()) of stack traces that we've
+ * already logged DropBox entries for. Guarded by itself. If
+ * something (rogue user app) forces this over
+ * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
+ */
+ private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
+ private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
+
+ /**
* Intent broadcast that we have tried to start, but are
* waiting for its application's process to be created. We only
* need one (instead of a list) because we always process broadcasts
@@ -9357,12 +9366,29 @@
public void handleApplicationStrictModeViolation(
IBinder app, int violationMask, ApplicationErrorReport.CrashInfo crashInfo) {
ProcessRecord r = findAppProcess(app);
- // TODO: implement
- Log.w(TAG, "handleApplicationStrictModeViolation.");
if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
- Integer crashFingerprint = crashInfo.stackTrace.hashCode();
- Log.d(TAG, "supposed to drop box for fingerprint " + crashFingerprint);
+ Integer stackFingerprint = crashInfo.stackTrace.hashCode();
+ boolean logIt = true;
+ synchronized (mAlreadyLoggedViolatedStacks) {
+ if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
+ logIt = false;
+ // TODO: sub-sample into EventLog for these, with
+ // the crashInfo.durationMillis? Then we'd get
+ // the relative pain numbers, without logging all
+ // the stack traces repeatedly. We'd want to do
+ // likewise in the client code, which also does
+ // dup suppression, before the Binder call.
+ } else {
+ if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
+ mAlreadyLoggedViolatedStacks.clear();
+ }
+ mAlreadyLoggedViolatedStacks.add(stackFingerprint);
+ }
+ }
+ if (logIt) {
+ addErrorToDropBox("strictmode", r, null, null, null, null, null, crashInfo);
+ }
}
if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
@@ -9375,6 +9401,8 @@
HashMap<String, Object> data = new HashMap<String, Object>();
data.put("result", result);
data.put("app", r);
+ data.put("violationMask", violationMask);
+ data.put("crashInfo", crashInfo);
msg.obj = data;
mHandler.sendMessage(msg);
@@ -9510,6 +9538,9 @@
sb.append("Subject: ").append(subject).append("\n");
}
sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
+ if (crashInfo.durationMillis != -1) {
+ sb.append("Duration-Millis: ").append(crashInfo.durationMillis).append("\n");
+ }
sb.append("\n");
// Do the rest in a worker thread to avoid blocking the caller on I/O
diff --git a/tools/aapt/Android.mk b/tools/aapt/Android.mk
index 499a7ac..b339a2c 100644
--- a/tools/aapt/Android.mk
+++ b/tools/aapt/Android.mk
@@ -4,6 +4,9 @@
# Android Asset Packaging Tool
#
+# This tool is prebuilt if we're doing an app-only build.
+ifeq ($(TARGET_BUILD_APPS),)
+
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
@@ -53,3 +56,4 @@
include $(BUILD_HOST_EXECUTABLE)
+endif # TARGET_BUILD_APPS
diff --git a/tools/aidl/Android.mk b/tools/aidl/Android.mk
index 944aeb6..2ad0728 100644
--- a/tools/aidl/Android.mk
+++ b/tools/aidl/Android.mk
@@ -2,6 +2,9 @@
#
# Copies files into the directory structure described by a manifest
+# This tool is prebuilt if we're doing an app-only build.
+ifeq ($(TARGET_BUILD_APPS),)
+
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
@@ -21,4 +24,4 @@
include $(BUILD_HOST_EXECUTABLE)
-
+endif # TARGET_BUILD_APPS