Merge change 20998
* changes:
Add norm() and map() to MathUtils.
diff --git a/api/current.xml b/api/current.xml
index 69d4d5c..b9fb85a 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -27892,6 +27892,23 @@
<parameter name="cursor" type="android.database.Cursor">
</parameter>
</method>
+<method name="onQueryEntitiesComplete"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+<parameter name="token" type="int">
+</parameter>
+<parameter name="cookie" type="java.lang.Object">
+</parameter>
+<parameter name="iterator" type="android.content.EntityIterator">
+</parameter>
+</method>
<method name="onUpdateComplete"
return="void"
abstract="false"
@@ -27974,6 +27991,29 @@
<parameter name="orderBy" type="java.lang.String">
</parameter>
</method>
+<method name="startQueryEntities"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="token" type="int">
+</parameter>
+<parameter name="cookie" type="java.lang.Object">
+</parameter>
+<parameter name="uri" type="android.net.Uri">
+</parameter>
+<parameter name="selection" type="java.lang.String">
+</parameter>
+<parameter name="selectionArgs" type="java.lang.String[]">
+</parameter>
+<parameter name="orderBy" type="java.lang.String">
+</parameter>
+</method>
<method name="startUpdate"
return="void"
abstract="false"
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 32a2891..e045105 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1701,6 +1701,14 @@
printRow(pw, TWO_COUNT_COLUMNS, "numPagers:", stats.numPagers, "inactivePageKB:",
(stats.totalBytes - stats.referencedBytes) / 1024);
printRow(pw, ONE_COUNT_COLUMN, "activePageKB:", stats.referencedBytes / 1024);
+
+ // Asset details.
+ String assetAlloc = AssetManager.getAssetAllocations();
+ if (assetAlloc != null) {
+ pw.println(" ");
+ pw.println(" Asset Allocations");
+ pw.print(assetAlloc);
+ }
}
private void printRow(PrintWriter pw, String format, Object...objs) {
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index 7ad6423..97d46f8 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -369,7 +369,26 @@
* forget to decode it. (See {@link android.net.Uri#getPathSegments} and
* {@link android.net.Uri#getLastPathSegment} for helpful utilities you can use here.)</li>
* </ul>
- *
+ *
+ * <p><b>Providing access to Content Providers that require permissions.</b> If your content
+ * provider declares an android:readPermission in your application's manifest, you must provide
+ * access to the search infrastructure to the search suggestion path by including a path-permission
+ * that grants android:readPermission access to "android.permission.GLOBAL_SEARCH". Granting access
+ * explicitly to the search infrastructure ensures it will be able to access the search suggestions
+ * without needing to know ahead of time any other details of the permissions protecting your
+ * provider. Content providers that require no permissions are already available to the search
+ * infrastructure. Here is an example of a provider that protects access to it with permissions,
+ * and provides read access to the search infrastructure to the path that it expects to receive the
+ * suggestion query on:
+ * <pre class="prettyprint">
+ * <provider android:name="MyProvider" android:authorities="myprovider"
+ * android:readPermission="android.permission.READ_MY_DATA"
+ * android:writePermission="android.permission.WRITE_MY_DATA">
+ * <path-permission android:path="/search_suggest_query"
+ * android:readPermission="android.permission.GLOBAL_SEARCH" />
+ * </provider>
+ * </pre>
+ *
* <p><b>Handling empty queries.</b> Your application should handle the "empty query"
* (no user text entered) case properly, and generate useful suggestions in this case. There are a
* number of ways to do this; Two are outlined here:
@@ -377,7 +396,7 @@
* unfiltered. (example: People)</li>
* <li>For a query search, you could simply present the most recent queries. This allows the user
* to quickly repeat a recent search.</li></ul>
- *
+ *
* <p><b>The Format of Individual Suggestions.</b> Your suggestions are communicated back to the
* Search Manager by way of a {@link android.database.Cursor Cursor}. The Search Manager will
* usually pass a null Projection, which means that your provider can simply return all appropriate
@@ -453,13 +472,42 @@
* <td align="center">No</td>
* </tr>
*
+ * <tr><th>{@link #SUGGEST_COLUMN_INTENT_EXTRA_DATA}</th>
+ * <td>If this column exists <i>and</i> this element exists at a given row, this is the
+ * data that will be used when forming the suggestion's intent. If not provided,
+ * the Intent's extra data field will be null. This column allows suggestions to
+ * provide additional arbitrary data which will be included as an extra under the
+ * key {@link #EXTRA_DATA_KEY}.</td>
+ * <td align="center">No.</td>
+ * </tr>
+ *
* <tr><th>{@link #SUGGEST_COLUMN_QUERY}</th>
* <td>If this column exists <i>and</i> this element exists at the given row, this is the
* data that will be used when forming the suggestion's query.</td>
* <td align="center">Required if suggestion's action is
* {@link android.content.Intent#ACTION_SEARCH ACTION_SEARCH}, optional otherwise.</td>
* </tr>
- *
+ *
+ * <tr><th>{@link #SUGGEST_COLUMN_SHORTCUT_ID}</th>
+ * <td>This column is used to indicate whether a search suggestion should be stored as a
+ * shortcut, and whether it should be validated. Shortcuts are usually formed when the
+ * user clicks a suggestion from Quick Search Box. If missing, the result will be
+ * stored as a shortcut and never refreshed. If set to
+ * {@link #SUGGEST_NEVER_MAKE_SHORTCUT}, the result will not be stored as a shortcut.
+ * Otherwise, the shortcut id will be used to check back for for an up to date
+ * suggestion using {@link #SUGGEST_URI_PATH_SHORTCUT}. Read more about shortcut
+ * refreshing in the section about
+ * <a href="#ExposingSearchSuggestionsToQuickSearchBox">exposing search suggestions to
+ * Quick Search Box</a>.</td>
+ * <td align="center">No. Only applicable to sources included in Quick Search Box.</td>
+ * </tr>
+ *
+ * <tr><th>{@link #SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING}</th>
+ * <td>This column is used to specify that a spinner should be shown in lieu of an icon2
+ * while the shortcut of this suggestion is being refreshed.</td>
+ * <td align="center">No. Only applicable to sources included in Quick Search Box.</td>
+ * </tr>
+ *
* <tr><th><i>Other Columns</i></th>
* <td>Finally, if you have defined any <a href="#ActionKeys">Action Keys</a> and you wish
* for them to have suggestion-specific definitions, you'll need to define one
@@ -536,7 +584,55 @@
* <a name="ExposingSearchSuggestionsToQuickSearchBox"></a>
* <h3>Exposing Search Suggestions to Quick Search Box</h3>
*
- * <p>
+ * <p>Once your application is setup to provide search suggestions, making them available to the
+ * globally accessable Quick Search Box is as easy as setting android:includeInGlobalSearch to
+ * "true" in your searchable metadata file. Beyond that, here are some more details of how
+ * suggestions interact with Quick Search Box, and optional ways that you may customize suggestions
+ * for your application.
+ *
+ * <p><b>Source Ranking:</b> Once your application's search results are made available to Quick
+ * Search Box, how they surface to the user for a particular query will depend on how many
+ * other apps have results for that query, and how often the user has clicked on your results
+ * compared to the other apps'. The apps with the best track record within Quick Search
+ * Box will get queried earlier and have a better chance of showing their results in the top few
+ * slots. If there are more results than can be displayed to the user within a screen or two, the
+ * results may spill into a "more results" section that groups the remaining results by
+ * source. The newest apps with little usage information are given middle of the road positioning
+ * until enough usage information is available to rank it as usual. The exact formula for ranking
+ * the results is not set in stone, but suffice it is to say that providing quality results will
+ * increase the likelihood that your app's suggestions are provided in a prominent position, and
+ * apps that provide lower quality suggestions will be more likely to be pushed into the spillover
+ * area.
+ *
+ * <p><b>Search Settings:</b> Each app that is available to Quick Search Box has an entry in the
+ * system settings where the user can enable or disable the inclusion of its results. Below the
+ * name of the application, each application may provide a brief description of what kind of
+ * information will be made available via a search settings description string pointed to by the
+ * android:searchSettingsDescription attribute in the searchable metadata.
+ *
+ * <p><b>Shortcuts:</b> Suggestions that are clicked on by the user are automatically made into
+ * shortcuts, or, copied so they can quickly be displayed to the user before querying any of
+ * the sources. Thereafter, the shortcutted suggestion will be displayed for the query that yielded
+ * the suggestion and for any prefixes of that query. When multiple shortcuts are made available
+ * for a given query, they are ranked based on recency and the number of clicks they have received.
+ * You can control how your suggestions are made into shortcuts, and whether they are refreshed,
+ * using the {@link #SUGGEST_COLUMN_SHORTCUT_ID} column:
+ * <ul><li>Suggestions that do not include a shortcut id column will be made into shortcuts and
+ * never refreshed. This makes sense for suggestions that refer to data that will never be changed
+ * or removed.</li>
+ * <li>Suggestions that include a shortcut id will be re-queried for a fresh version of the
+ * suggestion each time the shortcut is displayed. The shortcut will be quickly displayed with
+ * whatever data was most recently available until the refresh query returns, after which the
+ * suggestion will be dynamically refreshed with the up to date information. The shortcut refresh
+ * query will be sent to your suggestion provider with a uri of {@link #SUGGEST_URI_PATH_SHORTCUT}.
+ * The result should contain one suggestion using the same columns as the suggestion query, or be
+ * empty, indicating that the shortcut is no longer valid. Shortcut ids make sense when referring
+ * to data that may change over time, such as a contact's presence status. If a suggestion refers
+ * to data that could take longer to refresh, such as a network based refresh of a stock quote, you
+ * may include {@link #SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING} to show a progress spinner for the
+ * right hand icon until the refresh is complete.</li>
+ * <li>Finally, to prevent a suggestion from being copied into a shortcut, you may provide a
+ * shortcut id with a value of {@link #SUGGEST_NEVER_MAKE_SHORTCUT}.</li></ul>
*
* <a name="ActionKeys"></a>
* <h3>Action Keys</h3>
@@ -673,7 +769,7 @@
* entered.</td>
* <td align="center">No</td>
* </tr>
- *
+ *
* <tr><th>android:searchButtonText</th>
* <td>If provided, this text will replace the default text in the "Search" button.</td>
* <td align="center">No</td>
@@ -853,7 +949,48 @@
*
* </tbody>
* </table>
- *
+ *
+ * <p>Elements of search metadata that configure search suggestions being available to Quick Search
+ * Box:
+ * <table border="2" width="85%" align="center" frame="hsides" rules="rows">
+ *
+ * <thead>
+ * <tr><th>Attribute</th> <th>Description</th> <th>Required?</th></tr>
+ * </thead>
+ *
+ * <tr><th>android:includeInGlobalSearch</th>
+ * <td>If true, indicates the search suggestions provided by your application should be
+ * included in the globally accessible Quick Search Box. The attributes below are only
+ * applicable if this is set to true.</td>
+ * <td align="center">Yes</td>
+ * </tr>
+ *
+ * <tr><th>android:searchSettingsDescription</th>
+ * <td>If provided, provides a brief description of the search suggestions that are provided
+ * by your application to Quick Search Box, and will be displayed in the search settings
+ * entry for your application.</td>
+ * <td align="center">No</td>
+ * </tr>
+ *
+ * <tr><th>android:queryAfterZeroResults</th>
+ * <td>Indicates whether a source should be invoked for supersets of queries it has
+ * returned zero results for in the past. For example, if a source returned zero
+ * results for "bo", it would be ignored for "bob". If set to false, this source
+ * will only be ignored for a single session; the next time the search dialog is
+ * invoked, all sources will be queried. The default value is false.</td>
+ * <td align="center">No</td>
+ * </tr>
+ *
+ * <tr><th>android:searchSuggestThreshold</th>
+ * <td>Indicates the minimum number of characters needed to trigger a source from Quick
+ * Search Box. Only guarantees that a source will not be queried for anything shorter
+ * than the threshold. The default value is 0.</td>
+ * <td align="center">No</td>
+ * </tr>
+ *
+ * </tbody>
+ * </table>
+ *
* <p><b>Additional metadata for search action keys.</b> For each action key that you would like to
* define, you'll need to add an additional element defining that key, and using the attributes
* discussed in <a href="#ActionKeys">Action Keys</a>. A simple example is shown here:
@@ -1376,10 +1513,10 @@
/**
* Column name for suggestions cursor. <i>Optional.</i> This column is used to indicate whether
- * a search suggestion should be stored as a shortcut, and whether it should be validated. If
+ * a search suggestion should be stored as a shortcut, and whether it should be refreshed. If
* missing, the result will be stored as a shortcut and never validated. If set to
* {@link #SUGGEST_NEVER_MAKE_SHORTCUT}, the result will not be stored as a shortcut.
- * Otherwise, the shortcut id will be used to check back for validation via
+ * Otherwise, the shortcut id will be used to check back for an up to date suggestion using
* {@link #SUGGEST_URI_PATH_SHORTCUT}.
*/
public final static String SUGGEST_COLUMN_SHORTCUT_ID = "suggest_shortcut_id";
diff --git a/core/java/android/content/AsyncQueryHandler.java b/core/java/android/content/AsyncQueryHandler.java
index c5606ac..5e88de0 100644
--- a/core/java/android/content/AsyncQueryHandler.java
+++ b/core/java/android/content/AsyncQueryHandler.java
@@ -38,7 +38,8 @@
private static final int EVENT_ARG_INSERT = 2;
private static final int EVENT_ARG_UPDATE = 3;
private static final int EVENT_ARG_DELETE = 4;
-
+ private static final int EVENT_ARG_QUERY_ENTITIES = 5;
+
/* package */ final WeakReference<ContentResolver> mResolver;
private static Looper sLooper = null;
@@ -85,13 +86,25 @@
cursor.getCount();
}
} catch (Exception e) {
- Log.d(TAG, e.toString());
+ Log.w(TAG, e.toString());
cursor = null;
}
args.result = cursor;
break;
+ case EVENT_ARG_QUERY_ENTITIES:
+ EntityIterator iterator = null;
+ try {
+ iterator = resolver.queryEntities(args.uri, args.selection,
+ args.selectionArgs, args.orderBy);
+ } catch (Exception e) {
+ Log.w(TAG, e.toString());
+ }
+
+ args.result = iterator;
+ break;
+
case EVENT_ARG_INSERT:
args.result = resolver.insert(args.uri, args.values);
break;
@@ -104,7 +117,6 @@
case EVENT_ARG_DELETE:
args.result = resolver.delete(args.uri, args.selection, args.selectionArgs);
break;
-
}
// passing the original token value back to the caller
@@ -129,7 +141,7 @@
if (sLooper == null) {
HandlerThread thread = new HandlerThread("AsyncQueryWorker");
thread.start();
-
+
sLooper = thread.getLooper();
}
}
@@ -183,6 +195,44 @@
}
/**
+ * This method begins an asynchronous query for an {@link EntityIterator}.
+ * When the query is done {@link #onQueryEntitiesComplete} is called.
+ *
+ * @param token A token passed into {@link #onQueryComplete} to identify the
+ * query.
+ * @param cookie An object that gets passed into {@link #onQueryComplete}
+ * @param uri The URI, using the content:// scheme, for the content to
+ * retrieve.
+ * @param selection A filter declaring which rows to return, formatted as an
+ * SQL WHERE clause (excluding the WHERE itself). Passing null
+ * will return all rows for the given URI.
+ * @param selectionArgs You may include ?s in selection, which will be
+ * replaced by the values from selectionArgs, in the order that
+ * they appear in the selection. The values will be bound as
+ * Strings.
+ * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
+ * (excluding the ORDER BY itself). Passing null will use the
+ * default sort order, which may be unordered.
+ */
+ public void startQueryEntities(int token, Object cookie, Uri uri, String selection,
+ String[] selectionArgs, String orderBy) {
+ // Use the token as what so cancelOperations works properly
+ Message msg = mWorkerThreadHandler.obtainMessage(token);
+ msg.arg1 = EVENT_ARG_QUERY_ENTITIES;
+
+ WorkerArgs args = new WorkerArgs();
+ args.handler = this;
+ args.uri = uri;
+ args.selection = selection;
+ args.selectionArgs = selectionArgs;
+ args.orderBy = orderBy;
+ args.cookie = cookie;
+ msg.obj = args;
+
+ mWorkerThreadHandler.sendMessage(msg);
+ }
+
+ /**
* Attempts to cancel operation that has not already started. Note that
* there is no guarantee that the operation will be canceled. They still may
* result in a call to on[Query/Insert/Update/Delete]Complete after this
@@ -280,8 +330,8 @@
* Called when an asynchronous query is completed.
*
* @param token the token to identify the query, passed in from
- * {@link #startQuery}.
- * @param cookie the cookie object that's passed in from {@link #startQuery}.
+ * {@link #startQuery}.
+ * @param cookie the cookie object passed in from {@link #startQuery}.
* @param cursor The cursor holding the results from the query.
*/
protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
@@ -289,6 +339,17 @@
}
/**
+ * Called when an asynchronous query is completed.
+ *
+ * @param token The token to identify the query.
+ * @param cookie The cookie object.
+ * @param iterator The iterator holding the query results.
+ */
+ protected void onQueryEntitiesComplete(int token, Object cookie, EntityIterator iterator) {
+ // Empty
+ }
+
+ /**
* Called when an asynchronous insert is completed.
*
* @param token the token to identify the query, passed in from
@@ -338,13 +399,17 @@
int token = msg.what;
int event = msg.arg1;
-
+
// pass token back to caller on each callback.
switch (event) {
case EVENT_ARG_QUERY:
onQueryComplete(token, args.cookie, (Cursor) args.result);
break;
+ case EVENT_ARG_QUERY_ENTITIES:
+ onQueryEntitiesComplete(token, args.cookie, (EntityIterator)args.result);
+ break;
+
case EVENT_ARG_INSERT:
onInsertComplete(token, args.cookie, (Uri) args.result);
break;
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index 8ebe093..0bc8a9d 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -667,6 +667,11 @@
/**
* {@hide}
*/
+ public native static final String getAssetAllocations();
+
+ /**
+ * {@hide}
+ */
public native static final int getGlobalAssetManagerCount();
private native final int newTheme();
diff --git a/core/java/android/os/SystemProperties.java b/core/java/android/os/SystemProperties.java
index c3ae3c2..4a036ec 100644
--- a/core/java/android/os/SystemProperties.java
+++ b/core/java/android/os/SystemProperties.java
@@ -30,6 +30,9 @@
private static native String native_get(String key);
private static native String native_get(String key, String def);
+ private static native int native_get_int(String key, int def);
+ private static native long native_get_long(String key, long def);
+ private static native boolean native_get_boolean(String key, boolean def);
private static native void native_set(String key, String def);
/**
@@ -65,11 +68,10 @@
* @throws IllegalArgumentException if the key exceeds 32 characters
*/
public static int getInt(String key, int def) {
- try {
- return Integer.parseInt(get(key));
- } catch (NumberFormatException e) {
- return def;
+ if (key.length() > PROP_NAME_MAX) {
+ throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
}
+ return native_get_int(key, def);
}
/**
@@ -81,11 +83,10 @@
* @throws IllegalArgumentException if the key exceeds 32 characters
*/
public static long getLong(String key, long def) {
- try {
- return Long.parseLong(get(key));
- } catch (NumberFormatException e) {
- return def;
+ if (key.length() > PROP_NAME_MAX) {
+ throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
}
+ return native_get_long(key, def);
}
/**
@@ -102,27 +103,10 @@
* @throws IllegalArgumentException if the key exceeds 32 characters
*/
public static boolean getBoolean(String key, boolean def) {
- String value = get(key);
- // Deal with these quick cases first: not found, 0 and 1
- if (value.equals("")) {
- return def;
- } else if (value.equals("0")) {
- return false;
- } else if (value.equals("1")) {
- return true;
- // now for slower (and hopefully less common) cases
- } else if (value.equalsIgnoreCase("n") ||
- value.equalsIgnoreCase("no") ||
- value.equalsIgnoreCase("false") ||
- value.equalsIgnoreCase("off")) {
- return false;
- } else if (value.equalsIgnoreCase("y") ||
- value.equalsIgnoreCase("yes") ||
- value.equalsIgnoreCase("true") ||
- value.equalsIgnoreCase("on")) {
- return true;
+ if (key.length() > PROP_NAME_MAX) {
+ throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
}
- return def;
+ return native_get_boolean(key, def);
}
/**
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 04a0ec8..4405a53 100755
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -1032,7 +1032,7 @@
}
try {
String[] locStrings = mITts.getLanguage();
- if (locStrings.length == 3) {
+ if ((locStrings != null) && (locStrings.length == 3)) {
return new Locale(locStrings[0], locStrings[1], locStrings[2]);
} else {
return null;
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index 2c9e71e..b179a13 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -190,10 +190,12 @@
mBehavior = a.getInt(R.styleable.ProgressBar_indeterminateBehavior, mBehavior);
- final int resID = a.getResourceId(com.android.internal.R.styleable.ProgressBar_interpolator, -1);
+ final int resID = a.getResourceId(
+ com.android.internal.R.styleable.ProgressBar_interpolator,
+ android.R.anim.linear_interpolator); // default to linear interpolator
if (resID > 0) {
setInterpolator(context, resID);
- }
+ }
setMax(a.getInt(R.styleable.ProgressBar_max, mMax));
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 989286e..a2d3cd8 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -310,6 +310,15 @@
} else {
missingClasses += " " + line;
}
+ } catch (Throwable t) {
+ Log.e(TAG, "Error preloading " + line + ".", t);
+ if (t instanceof Error) {
+ throw (Error) t;
+ }
+ if (t instanceof RuntimeException) {
+ throw (RuntimeException) t;
+ }
+ throw new RuntimeException(t);
}
}
diff --git a/core/java/com/android/internal/widget/ContactHeaderWidget.java b/core/java/com/android/internal/widget/ContactHeaderWidget.java
index 58fa0ba..462143f 100644
--- a/core/java/com/android/internal/widget/ContactHeaderWidget.java
+++ b/core/java/com/android/internal/widget/ContactHeaderWidget.java
@@ -35,6 +35,7 @@
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.Intents;
import android.provider.ContactsContract.PhoneLookup;
+import android.provider.ContactsContract.Presence;
import android.provider.ContactsContract.RawContacts;
import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.provider.SocialContract.Activities;
@@ -61,12 +62,13 @@
private TextView mPhoneticNameView;
private CheckBox mStarredView;
private ImageView mPhotoView;
+ private ImageView mPresenceView;
private TextView mStatusView;
private int mNoPhotoResource;
private QueryHandler mQueryHandler;
protected long mContactId;
- protected Uri mContactDataUri;
+ protected Uri mContactSummaryUri;
protected Uri mContactUri;
protected Uri mStatusUri;
@@ -84,12 +86,14 @@
Contacts.DISPLAY_NAME,
Contacts.STARRED,
Contacts.PHOTO_ID,
+ Contacts.PRESENCE_STATUS,
};
protected static final int HEADER_DISPLAY_NAME_COLUMN_INDEX = 0;
//TODO: We need to figure out how we're going to get the phonetic name.
//static final int HEADER_PHONETIC_NAME_COLUMN_INDEX
protected static final int HEADER_STARRED_COLUMN_INDEX = 1;
protected static final int HEADER_PHOTO_ID_COLUMN_INDEX = 2;
+ protected static final int HEADER_PRESENCE_STATUS_COLUMN_INDEX = 3;
//Projection used for finding the most recent social status.
protected static final String[] SOCIAL_PROJECTION = new String[] {
@@ -144,6 +148,8 @@
mPhotoView.setOnClickListener(this);
mPhotoView.setOnLongClickListener(this);
+ mPresenceView = (ImageView) findViewById(R.id.presence);
+
mStatusView = (TextView)findViewById(R.id.status);
// Set the photo with a random "no contact" image
@@ -250,7 +256,7 @@
public void bindFromContactId(long contactId) {
mContactId = contactId;
mContactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, mContactId);
- mContactDataUri = Uri.withAppendedPath(mContactUri, Contacts.Data.CONTENT_DIRECTORY);
+ mContactSummaryUri = ContentUris.withAppendedId(Contacts.CONTENT_SUMMARY_URI, mContactId);
mStatusUri = ContentUris.withAppendedId(
SocialContract.Activities.CONTENT_CONTACT_STATUS_URI, mContactId);
redrawHeader();
@@ -317,8 +323,8 @@
}
protected void redrawHeader() {
- if (mContactDataUri != null) {
- mQueryHandler.startQuery(TOKEN_CONTACT_INFO, null, mContactDataUri, HEADER_PROJECTION,
+ if (mContactSummaryUri != null) {
+ mQueryHandler.startQuery(TOKEN_CONTACT_INFO, null, mContactSummaryUri, HEADER_PROJECTION,
null, null, null);
}
@@ -352,6 +358,10 @@
photoBitmap = loadPlaceholderPhoto(null);
}
mPhotoView.setImageBitmap(photoBitmap);
+
+ //Set the presence status
+ int presence = c.getInt(HEADER_PRESENCE_STATUS_COLUMN_INDEX);
+ mPresenceView.setImageResource(Presence.getPresenceIconResourceId(presence));
}
}
diff --git a/core/jni/android_os_SystemProperties.cpp b/core/jni/android_os_SystemProperties.cpp
index ca4fa11..406884b 100644
--- a/core/jni/android_os_SystemProperties.cpp
+++ b/core/jni/android_os_SystemProperties.cpp
@@ -36,9 +36,9 @@
"key must not be null.");
goto error;
}
-
+
key = env->GetStringUTFChars(keyJ, NULL);
-
+
len = property_get(key, buf, "");
if ((len <= 0) && (defJ != NULL)) {
rvJ = defJ;
@@ -47,9 +47,9 @@
} else {
rvJ = env->NewStringUTF("");
}
-
+
env->ReleaseStringUTFChars(keyJ, key);
-
+
error:
return rvJ;
}
@@ -60,6 +60,101 @@
return SystemProperties_getSS(env, clazz, keyJ, NULL);
}
+static jint SystemProperties_get_int(JNIEnv *env, jobject clazz,
+ jstring keyJ, jint defJ)
+{
+ int len;
+ const char* key;
+ char buf[PROPERTY_VALUE_MAX];
+ jint result = defJ;
+
+ if (keyJ == NULL) {
+ jniThrowException(env, "java/lang/NullPointerException",
+ "key must not be null.");
+ goto error;
+ }
+
+ key = env->GetStringUTFChars(keyJ, NULL);
+
+ len = property_get(key, buf, "");
+ if (len > 0) {
+ jint temp;
+ if (sscanf(buf, "%d", &temp) == 1)
+ result = temp;
+ }
+
+ env->ReleaseStringUTFChars(keyJ, key);
+
+error:
+ return result;
+}
+
+static jlong SystemProperties_get_long(JNIEnv *env, jobject clazz,
+ jstring keyJ, jlong defJ)
+{
+ int len;
+ const char* key;
+ char buf[PROPERTY_VALUE_MAX];
+ jlong result = defJ;
+
+ if (keyJ == NULL) {
+ jniThrowException(env, "java/lang/NullPointerException",
+ "key must not be null.");
+ goto error;
+ }
+
+ key = env->GetStringUTFChars(keyJ, NULL);
+
+ len = property_get(key, buf, "");
+ if (len > 0) {
+ jlong temp;
+ if (sscanf(buf, "%lld", &temp) == 1)
+ result = temp;
+ }
+
+ env->ReleaseStringUTFChars(keyJ, key);
+
+error:
+ return result;
+}
+
+static jboolean SystemProperties_get_boolean(JNIEnv *env, jobject clazz,
+ jstring keyJ, jboolean defJ)
+{
+ int len;
+ const char* key;
+ char buf[PROPERTY_VALUE_MAX];
+ jboolean result = defJ;
+
+ if (keyJ == NULL) {
+ jniThrowException(env, "java/lang/NullPointerException",
+ "key must not be null.");
+ goto error;
+ }
+
+ key = env->GetStringUTFChars(keyJ, NULL);
+
+ len = property_get(key, buf, "");
+ if (len == 1) {
+ char ch = buf[0];
+ if (ch == '0' || ch == 'n')
+ result = false;
+ else if (ch == '1' || ch == 'y')
+ result = true;
+ } else if (len > 1) {
+ if (!strcmp(buf, "no") || !strcmp(buf, "false") || !strcmp(buf, "off")) {
+ result = false;
+ } else if (!strcmp(buf, "yes") || !strcmp(buf, "true") || !strcmp(buf, "on")) {
+ result = true;
+ }
+ }
+
+ env->ReleaseStringUTFChars(keyJ, key);
+
+error:
+ return result;
+}
+
static void SystemProperties_set(JNIEnv *env, jobject clazz,
jstring keyJ, jstring valJ)
{
@@ -94,6 +189,12 @@
(void*) SystemProperties_getS },
{ "native_get", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
(void*) SystemProperties_getSS },
+ { "native_get_int", "(Ljava/lang/String;I)I",
+ (void*) SystemProperties_get_int },
+ { "native_get_long", "(Ljava/lang/String;J)J",
+ (void*) SystemProperties_get_long },
+ { "native_get_boolean", "(Ljava/lang/String;Z)Z",
+ (void*) SystemProperties_get_boolean },
{ "native_set", "(Ljava/lang/String;Ljava/lang/String;)V",
(void*) SystemProperties_set },
};
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index 66b2506..562cc8f 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -1536,6 +1536,22 @@
return Asset::getGlobalCount();
}
+static jobject android_content_AssetManager_getAssetAllocations(JNIEnv* env, jobject clazz)
+{
+ String8 alloc = Asset::getAssetAllocations();
+ if (alloc.length() <= 0) {
+ return NULL;
+ }
+
+ jstring str = env->NewStringUTF(alloc.string());
+ if (str == NULL) {
+ doThrow(env, "java/lang/OutOfMemoryError");
+ return NULL;
+ }
+
+ return str;
+}
+
static jint android_content_AssetManager_getGlobalAssetManagerCount(JNIEnv* env, jobject clazz)
{
return AssetManager::getGlobalCount();
@@ -1646,6 +1662,8 @@
(void*) android_content_AssetManager_destroy },
{ "getGlobalAssetCount", "()I",
(void*) android_content_AssetManager_getGlobalAssetCount },
+ { "getAssetAllocations", "()Ljava/lang/String;",
+ (void*) android_content_AssetManager_getAssetAllocations },
{ "getGlobalAssetManagerCount", "()I",
(void*) android_content_AssetManager_getGlobalAssetCount },
};
diff --git a/core/res/res/layout-ja/contact_header_name.xml b/core/res/res/layout-ja/contact_header_name.xml
index 03332b1..20df5c6 100644
--- a/core/res/res/layout-ja/contact_header_name.xml
+++ b/core/res/res/layout-ja/contact_header_name.xml
@@ -25,6 +25,8 @@
<TextView android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="end"
android:textAppearance="?android:attr/textAppearanceLargeInverse"
android:textColor="@android:color/secondary_text_light"
/>
@@ -32,6 +34,8 @@
<TextView android:id="@+id/phonetic_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="end"
android:textAppearance="?android:attr/textAppearanceSmallInverse"
android:textColor="@android:color/secondary_text_light"
/>
diff --git a/core/res/res/layout/contact_header.xml b/core/res/res/layout/contact_header.xml
index 06cd38c..73e379b 100644
--- a/core/res/res/layout/contact_header.xml
+++ b/core/res/res/layout/contact_header.xml
@@ -48,6 +48,13 @@
</LinearLayout>
+ <ImageView
+ android:id="@+id/presence"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingLeft="3dip"
+ android:paddingRight="6dip"/>
+
<CheckBox
android:id="@+id/star"
android:layout_width="wrap_content"
diff --git a/core/res/res/layout/contact_header_name.xml b/core/res/res/layout/contact_header_name.xml
index aec943e..77751c3 100644
--- a/core/res/res/layout/contact_header_name.xml
+++ b/core/res/res/layout/contact_header_name.xml
@@ -21,6 +21,6 @@
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLargeInverse"
android:textColor="@android:color/secondary_text_light"
- android:maxLines="2"
+ android:singleLine="true"
android:ellipsize="end"
/>
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 285fdc0..24bbea5 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -396,7 +396,7 @@
jint len = _env->GetArrayLength(data);
LOG_API("nAllocationRead_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
jint *ptr = _env->GetIntArrayElements(data, NULL);
- rsAllocationData((RsAllocation)alloc, ptr);
+ rsAllocationRead((RsAllocation)alloc, ptr);
_env->ReleaseIntArrayElements(data, ptr, JNI_COMMIT);
}
@@ -405,9 +405,9 @@
{
RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
jint len = _env->GetArrayLength(data);
- LOG_API("nAllocationRead_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
+ LOG_API("nAllocationRead_f, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
- rsAllocationData((RsAllocation)alloc, ptr);
+ rsAllocationRead((RsAllocation)alloc, ptr);
_env->ReleaseFloatArrayElements(data, ptr, JNI_COMMIT);
}
diff --git a/include/utils/Asset.h b/include/utils/Asset.h
index 453a204..5908bcc 100644
--- a/include/utils/Asset.h
+++ b/include/utils/Asset.h
@@ -45,6 +45,7 @@
virtual ~Asset(void);
static int32_t getGlobalCount();
+ static String8 getAssetAllocations();
/* used when opening an asset */
typedef enum AccessMode {
@@ -110,6 +111,12 @@
virtual int openFileDescriptor(off_t* outStart, off_t* outLength) const = 0;
/*
+ * Return whether this asset's buffer is allocated in RAM (not mmapped).
+ * Note: not virtual so it is safe to call even when being destroyed.
+ */
+ virtual bool isAllocated(void) const { return false; }
+
+ /*
* Get a string identifying the asset's source. This might be a full
* path, it might be a colon-separated list of identifiers.
*
@@ -197,6 +204,9 @@
AccessMode mAccessMode; // how the asset was opened
String8 mAssetSource; // debug string
+
+ Asset* mNext; // linked list.
+ Asset* mPrev;
};
@@ -239,6 +249,7 @@
virtual off_t getLength(void) const { return mLength; }
virtual off_t getRemainingLength(void) const { return mLength-mOffset; }
virtual int openFileDescriptor(off_t* outStart, off_t* outLength) const;
+ virtual bool isAllocated(void) const { return mBuf != NULL; }
private:
off_t mStart; // absolute file offset of start of chunk
@@ -295,6 +306,7 @@
virtual off_t getLength(void) const { return mUncompressedLen; }
virtual off_t getRemainingLength(void) const { return mUncompressedLen-mOffset; }
virtual int openFileDescriptor(off_t* outStart, off_t* outLength) const { return -1; }
+ virtual bool isAllocated(void) const { return mBuf != NULL; }
private:
off_t mStart; // offset to start of compressed data
diff --git a/libs/utils/Asset.cpp b/libs/utils/Asset.cpp
index 23cb72d..4295123 100644
--- a/libs/utils/Asset.cpp
+++ b/libs/utils/Asset.cpp
@@ -27,6 +27,7 @@
#include <utils/ZipUtils.h>
#include <utils/ZipFileRO.h>
#include <utils/Log.h>
+#include <utils/threads.h>
#include <string.h>
#include <memory.h>
@@ -40,24 +41,71 @@
# define O_BINARY 0
#endif
-static volatile int32_t gCount = 0;
+static Mutex gAssetLock;
+static int32_t gCount = 0;
+static Asset* gHead = NULL;
+static Asset* gTail = NULL;
int32_t Asset::getGlobalCount()
{
+ AutoMutex _l(gAssetLock);
return gCount;
}
+String8 Asset::getAssetAllocations()
+{
+ AutoMutex _l(gAssetLock);
+ String8 res;
+ Asset* cur = gHead;
+ while (cur != NULL) {
+ if (cur->isAllocated()) {
+ res.append(" ");
+ res.append(cur->getAssetSource());
+ off_t size = (cur->getLength()+512)/1024;
+ char buf[64];
+ sprintf(buf, ": %dK\n", (int)size);
+ res.append(buf);
+ }
+ cur = cur->mNext;
+ }
+
+ return res;
+}
+
Asset::Asset(void)
: mAccessMode(ACCESS_UNKNOWN)
{
- int count = android_atomic_inc(&gCount)+1;
- //LOGI("Creating Asset %p #%d\n", this, count);
+ AutoMutex _l(gAssetLock);
+ gCount++;
+ mNext = mPrev = NULL;
+ if (gTail == NULL) {
+ gHead = gTail = this;
+ } else {
+ mPrev = gTail;
+ gTail->mNext = this;
+ gTail = this;
+ }
+ //LOGI("Creating Asset %p #%d\n", this, gCount);
}
Asset::~Asset(void)
{
- int count = android_atomic_dec(&gCount);
- //LOGI("Destroying Asset in %p #%d\n", this, count);
+ AutoMutex _l(gAssetLock);
+ gCount--;
+ if (gHead == this) {
+ gHead = mNext;
+ }
+ if (gTail == this) {
+ gTail = mPrev;
+ }
+ if (mNext != NULL) {
+ mNext->mPrev = mPrev;
+ }
+ if (mPrev != NULL) {
+ mPrev->mNext = mNext;
+ }
+ mNext = mPrev = NULL;
+ //LOGI("Destroying Asset in %p #%d\n", this, gCount);
}
/*
diff --git a/packages/TtsService/src/android/tts/TtsService.java b/packages/TtsService/src/android/tts/TtsService.java
index 1b99d32..cd24727 100755
--- a/packages/TtsService/src/android/tts/TtsService.java
+++ b/packages/TtsService/src/android/tts/TtsService.java
@@ -172,10 +172,18 @@
@Override
public void onDestroy() {
super.onDestroy();
+
+ // TODO replace the call to stopAll() with a method to clear absolutely all upcoming
+ // uses of the native synth, including synthesis to a file, and delete files for which
+ // synthesis was not complete.
+ stopAll("");
+
// Don't hog the media player
cleanUpPlayer();
- sNativeSynth.shutdown();
+ if (sNativeSynth != null) {
+ sNativeSynth.shutdown();
+ }
sNativeSynth = null;
// Unregister all callbacks.
@@ -243,38 +251,70 @@
private int setSpeechRate(String callingApp, int rate) {
- if (isDefaultEnforced()) {
- return sNativeSynth.setSpeechRate(getDefaultRate());
- } else {
- return sNativeSynth.setSpeechRate(rate);
+ int res = TextToSpeech.ERROR;
+ try {
+ if (isDefaultEnforced()) {
+ res = sNativeSynth.setSpeechRate(getDefaultRate());
+ } else {
+ res = sNativeSynth.setSpeechRate(rate);
+ }
+ } catch (NullPointerException e) {
+ // synth will become null during onDestroy()
+ res = TextToSpeech.ERROR;
}
+ return res;
}
private int setPitch(String callingApp, int pitch) {
- return sNativeSynth.setPitch(pitch);
+ int res = TextToSpeech.ERROR;
+ try {
+ res = sNativeSynth.setPitch(pitch);
+ } catch (NullPointerException e) {
+ // synth will become null during onDestroy()
+ res = TextToSpeech.ERROR;
+ }
+ return res;
}
private int isLanguageAvailable(String lang, String country, String variant) {
//Log.v("TtsService", "TtsService.isLanguageAvailable(" + lang + ", " + country + ", " +variant+")");
- return sNativeSynth.isLanguageAvailable(lang, country, variant);
+ int res = TextToSpeech.LANG_NOT_SUPPORTED;
+ try {
+ res = sNativeSynth.isLanguageAvailable(lang, country, variant);
+ } catch (NullPointerException e) {
+ // synth will become null during onDestroy()
+ res = TextToSpeech.LANG_NOT_SUPPORTED;
+ }
+ return res;
}
private String[] getLanguage() {
- return sNativeSynth.getLanguage();
+ try {
+ return sNativeSynth.getLanguage();
+ } catch (Exception e) {
+ return null;
+ }
}
private int setLanguage(String callingApp, String lang, String country, String variant) {
Log.v("TtsService", "TtsService.setLanguage(" + lang + ", " + country + ", " + variant + ")");
- if (isDefaultEnforced()) {
- return sNativeSynth.setLanguage(getDefaultLanguage(), getDefaultCountry(),
- getDefaultLocVariant());
- } else {
- return sNativeSynth.setLanguage(lang, country, variant);
+ int res = TextToSpeech.ERROR;
+ try {
+ if (isDefaultEnforced()) {
+ res = sNativeSynth.setLanguage(getDefaultLanguage(), getDefaultCountry(),
+ getDefaultLocVariant());
+ } else {
+ res = sNativeSynth.setLanguage(lang, country, variant);
+ }
+ } catch (NullPointerException e) {
+ // synth will become null during onDestroy()
+ res = TextToSpeech.ERROR;
}
+ return res;
}
@@ -402,7 +442,12 @@
}
if ((mCurrentSpeechItem != null) &&
mCurrentSpeechItem.mCallingApp.equals(callingApp)) {
- result = sNativeSynth.stop();
+ try {
+ result = sNativeSynth.stop();
+ } catch (NullPointerException e1) {
+ // synth will become null during onDestroy()
+ result = TextToSpeech.ERROR;
+ }
mKillList.put(mCurrentSpeechItem, true);
if (mPlayer != null) {
try {
@@ -434,7 +479,8 @@
/**
- * Stops all speech output and removes any utterances still in the queue globally.
+ * Stops all speech output and removes any utterances still in the queue globally, except
+ * those intended to be synthesized to file.
*/
private int stopAll(String callingApp) {
int result = TextToSpeech.ERROR;
@@ -451,7 +497,12 @@
if ((mCurrentSpeechItem != null) &&
((mCurrentSpeechItem.mType != SpeechItem.TEXT_TO_FILE) ||
mCurrentSpeechItem.mCallingApp.equals(callingApp))) {
- result = sNativeSynth.stop();
+ try {
+ result = sNativeSynth.stop();
+ } catch (NullPointerException e1) {
+ // synth will become null during onDestroy()
+ result = TextToSpeech.ERROR;
+ }
mKillList.put(mCurrentSpeechItem, true);
if (mPlayer != null) {
try {
@@ -591,7 +642,12 @@
if (speechRate.length() > 0){
setSpeechRate("", Integer.parseInt(speechRate));
}
- sNativeSynth.speak(speechItem.mText, streamType);
+ try {
+ sNativeSynth.speak(speechItem.mText, streamType);
+ } catch (NullPointerException e) {
+ // synth will become null during onDestroy()
+ Log.v("TtsService", " null synth, can't speak");
+ }
}
} catch (InterruptedException e) {
Log.e("TtsService", "TTS speakInternalOnly(): tryLock interrupted");
@@ -660,7 +716,12 @@
if (speechRate.length() > 0){
setSpeechRate("", Integer.parseInt(speechRate));
}
- sNativeSynth.synthesizeToFile(speechItem.mText, speechItem.mFilename);
+ try {
+ sNativeSynth.synthesizeToFile(speechItem.mText, speechItem.mFilename);
+ } catch (NullPointerException e) {
+ // synth will become null during onDestroy()
+ Log.v("TtsService", " null synth, can't synthesize to file");
+ }
}
} catch (InterruptedException e) {
Log.e("TtsService", "TTS synthToFileInternalOnly(): tryLock interrupted");
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index 78db6f9..5439f8b 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -1009,8 +1009,7 @@
if (success) {
// delete any hosts that didn't manage to get connected (should happen)
// if it matters, they'll be reconnected.
- final int N = mHosts.size();
- for (int i=0; i<N; i++) {
+ for (int i=mHosts.size()-1; i>=0; i--) {
pruneHostLocked(mHosts.get(i));
}
} else {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 6907443..c59c9cc3 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -4455,7 +4455,7 @@
}
final void appNotRespondingLocked(ProcessRecord app, HistoryRecord activity,
- final String annotation) {
+ HistoryRecord reportedActivity, final String annotation) {
if (app.notResponding || app.crashing) {
return;
}
@@ -4483,8 +4483,13 @@
StringBuilder info = mStringBuilder;
info.setLength(0);
- info.append("ANR (application not responding) in process: ");
+ info.append("ANR in process: ");
info.append(app.processName);
+ if (reportedActivity != null && reportedActivity.app != null) {
+ info.append(" (last in ");
+ info.append(reportedActivity.app.processName);
+ info.append(")");
+ }
if (annotation != null) {
info.append("\nAnnotation: ");
info.append(annotation);
@@ -4504,10 +4509,44 @@
} else {
// Dumping traces to a file so dump all active processes we know about
synchronized (this) {
- for (int i = mLRUProcesses.size() - 1 ; i >= 0 ; i--) {
+ // First, these are the most important processes.
+ final int[] imppids = new int[3];
+ int i=0;
+ imppids[0] = app.pid;
+ i++;
+ if (reportedActivity != null && reportedActivity.app != null
+ && reportedActivity.app.thread != null
+ && reportedActivity.app.pid != app.pid) {
+ imppids[i] = reportedActivity.app.pid;
+ i++;
+ }
+ imppids[i] = Process.myPid();
+ for (i=0; i<imppids.length && imppids[i] != 0; i++) {
+ Process.sendSignal(imppids[i], Process.SIGNAL_QUIT);
+ synchronized (this) {
+ try {
+ wait(200);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+ for (i = mLRUProcesses.size() - 1 ; i >= 0 ; i--) {
ProcessRecord r = mLRUProcesses.get(i);
- if (r.thread != null) {
+ boolean done = false;
+ for (int j=0; j<imppids.length && imppids[j] != 0; j++) {
+ if (imppids[j] == r.pid) {
+ done = true;
+ break;
+ }
+ }
+ if (!done && r.thread != null) {
Process.sendSignal(r.pid, Process.SIGNAL_QUIT);
+ synchronized (this) {
+ try {
+ wait(200);
+ } catch (InterruptedException e) {
+ }
+ }
}
}
}
@@ -4571,7 +4610,7 @@
if (!dir.exists()) {
fileReady = dir.mkdirs();
FileUtils.setPermissions(dir.getAbsolutePath(),
- FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IRWXO, -1, -1);
+ FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IXOTH, -1, -1);
} else if (dir.isDirectory()) {
fileReady = true;
}
@@ -4581,6 +4620,18 @@
Log.i(TAG, "Removing old ANR trace file from " + tracesPath);
fileReady = f.delete();
}
+
+ if (removeExisting) {
+ try {
+ f.createNewFile();
+ FileUtils.setPermissions(f.getAbsolutePath(),
+ FileUtils.S_IRWXU | FileUtils.S_IRWXG
+ | FileUtils.S_IWOTH | FileUtils.S_IROTH, -1, -1);
+ fileReady = true;
+ } catch (IOException e) {
+ Log.w(TAG, "Unable to make ANR traces file", e);
+ }
+ }
}
return fileReady;
@@ -10639,7 +10690,7 @@
}
if (timeout != null && mLRUProcesses.contains(proc)) {
Log.w(TAG, "Timeout executing service: " + timeout);
- appNotRespondingLocked(proc, null, "Executing service "
+ appNotRespondingLocked(proc, null, null, "Executing service "
+ timeout.name);
} else {
Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
@@ -11434,7 +11485,8 @@
}
if (app != null) {
- appNotRespondingLocked(app, null, "Broadcast of " + r.intent.toString());
+ appNotRespondingLocked(app, null, null,
+ "Broadcast of " + r.intent.toString());
}
if (mPendingBroadcast == r) {
diff --git a/services/java/com/android/server/am/HistoryRecord.java b/services/java/com/android/server/am/HistoryRecord.java
index b3fc313..84ded22 100644
--- a/services/java/com/android/server/am/HistoryRecord.java
+++ b/services/java/com/android/server/am/HistoryRecord.java
@@ -470,7 +470,8 @@
}
if (r.app.instrumentationClass == null) {
- service.appNotRespondingLocked(r.app, r, "keyDispatchingTimedOut");
+ service.appNotRespondingLocked(r.app, r, this,
+ "keyDispatchingTimedOut");
} else {
Bundle info = new Bundle();
info.putString("shortMsg", "keyDispatchingTimedOut");
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
index f1207e4..af59126 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
@@ -277,10 +277,12 @@
}
if (header != null) {
- userData = new byte[header.length + textPart.length];
+ // Need 1 byte for UDHL
+ userData = new byte[header.length + textPart.length + 1];
- System.arraycopy(header, 0, userData, 0, header.length);
- System.arraycopy(textPart, 0, userData, header.length, textPart.length);
+ userData[0] = (byte)header.length;
+ System.arraycopy(header, 0, userData, 1, header.length);
+ System.arraycopy(textPart, 0, userData, header.length + 1, textPart.length);
}
else {
userData = textPart;
diff --git a/tests/FrameworkTest/tests/src/android/widget/AutoCompleteTextViewCallbacks.java b/tests/FrameworkTest/tests/src/android/widget/AutoCompleteTextViewCallbacks.java
index 89421e48..29000dd 100644
--- a/tests/FrameworkTest/tests/src/android/widget/AutoCompleteTextViewCallbacks.java
+++ b/tests/FrameworkTest/tests/src/android/widget/AutoCompleteTextViewCallbacks.java
@@ -19,8 +19,8 @@
import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;
import android.test.FlakyTest;
-import android.test.suitebuilder.annotation.MediumTest;
+// TODO: tests fail intermittently. Add back MediumTest annotation when fixed
public class AutoCompleteTextViewCallbacks
extends ActivityInstrumentationTestCase2<AutoCompleteTextViewSimple> {
@@ -32,7 +32,6 @@
/** Test that the initial popup of the suggestions does not select anything.
*/
- @MediumTest
@FlakyTest(tolerance=3)
public void testPopupNoSelection() throws Exception {
AutoCompleteTextViewSimple theActivity = getActivity();
@@ -57,7 +56,6 @@
}
/** Test that arrow-down into the popup calls the onSelected callback. */
- @MediumTest
@FlakyTest(tolerance=3)
public void testPopupEnterSelection() throws Exception {
AutoCompleteTextViewSimple theActivity = getActivity();
@@ -95,7 +93,6 @@
}
/** Test that arrow-up out of the popup calls the onNothingSelected callback */
- @MediumTest
@FlakyTest(tolerance=3)
public void testPopupLeaveSelection() {
AutoCompleteTextViewSimple theActivity = getActivity();
diff --git a/tests/FrameworkTest/tests/src/android/widget/AutoCompleteTextViewPopup.java b/tests/FrameworkTest/tests/src/android/widget/AutoCompleteTextViewPopup.java
index 1e4cd20..c48c056 100644
--- a/tests/FrameworkTest/tests/src/android/widget/AutoCompleteTextViewPopup.java
+++ b/tests/FrameworkTest/tests/src/android/widget/AutoCompleteTextViewPopup.java
@@ -20,10 +20,11 @@
import android.test.ActivityInstrumentationTestCase2;
import android.test.FlakyTest;
import android.test.suitebuilder.annotation.MediumTest;
-import android.util.Log;
/**
* A collection of tests on aspects of the AutoCompleteTextView's popup
+ *
+ * TODO: tests fail intermittently. Add back MediumTest annotation when fixed
*/
public class AutoCompleteTextViewPopup
extends ActivityInstrumentationTestCase2<AutoCompleteTextViewSimple> {
@@ -40,7 +41,6 @@
}
/** Test that we can move the selection and it responds as expected */
- @MediumTest
@FlakyTest(tolerance=3)
public void testPopupSetListSelection() throws Throwable {
AutoCompleteTextViewSimple theActivity = getActivity();
@@ -73,7 +73,6 @@
}
/** Test that we can look at the selection as we move around */
- @MediumTest
@FlakyTest(tolerance=3)
public void testPopupGetListSelection() throws Throwable {
AutoCompleteTextViewSimple theActivity = getActivity();
@@ -101,7 +100,6 @@
}
/** Test that we can clear the selection */
- @MediumTest
@FlakyTest(tolerance=3)
public void testPopupClearListSelection() throws Throwable {
AutoCompleteTextViewSimple theActivity = getActivity();
@@ -135,7 +133,6 @@
}
/** Make sure we handle an empty adapter properly */
- @MediumTest
@FlakyTest(tolerance=3)
public void testPopupNavigateNoAdapter() throws Throwable {
AutoCompleteTextViewSimple theActivity = getActivity();
@@ -170,7 +167,6 @@
}
/** Test the show/hide behavior of the drop-down. */
- @MediumTest
@FlakyTest(tolerance=3)
public void testPopupShow() throws Throwable {
AutoCompleteTextViewSimple theActivity = getActivity();
diff --git a/tools/preload/20090811.compiled b/tools/preload/20090811.compiled
new file mode 100644
index 0000000..dd61487
--- /dev/null
+++ b/tools/preload/20090811.compiled
Binary files differ
diff --git a/tools/preload/ClassRank.java b/tools/preload/ClassRank.java
index 3699b89..c562d5c 100644
--- a/tools/preload/ClassRank.java
+++ b/tools/preload/ClassRank.java
@@ -26,7 +26,7 @@
* Increase this number to add more weight to classes which were loaded
* earlier.
*/
- static final int SEQUENCE_WEIGHT = 500; // 5 ms
+ static final int SEQUENCE_WEIGHT = 500; // 0.5ms
static final int BUCKET_SIZE = 5;
diff --git a/tools/preload/LoadedClass.java b/tools/preload/LoadedClass.java
index 5782807..9ef17f5 100644
--- a/tools/preload/LoadedClass.java
+++ b/tools/preload/LoadedClass.java
@@ -15,10 +15,7 @@
*/
import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
/**
* A loaded class.
@@ -54,7 +51,7 @@
}
void measureMemoryUsage() {
- this.memoryUsage = MemoryUsage.forClass(name);
+// this.memoryUsage = MemoryUsage.forClass(name);
}
int mlt = -1;
@@ -102,31 +99,20 @@
}
}
- /**
- * Counts loads by apps.
- */
- int appLoads() {
- return operationsByApps(loads);
+ /** Returns names of apps that loaded this class. */
+ Set<String> applicationNames() {
+ Set<String> appNames = new HashSet<String>();
+ addProcessNames(loads, appNames);
+ addProcessNames(initializations, appNames);
+ return appNames;
}
- /**
- * Counts inits by apps.
- */
- int appInits() {
- return operationsByApps(initializations);
- }
-
- /**
- * Counts number of app operations in the given list.
- */
- private static int operationsByApps(List<Operation> operations) {
- int byApps = 0;
- for (Operation operation : operations) {
+ private void addProcessNames(List<Operation> ops, Set<String> appNames) {
+ for (Operation operation : ops) {
if (operation.process.isApplication()) {
- byApps++;
+ appNames.add(operation.process.name);
}
}
- return byApps;
}
public int compareTo(LoadedClass o) {
@@ -160,4 +146,8 @@
return false;
}
+
+ public boolean isPreloadable() {
+ return systemClass && Policy.isPreloadableClass(name);
+ }
}
diff --git a/tools/preload/Policy.java b/tools/preload/Policy.java
index 554966b..ade889e3 100644
--- a/tools/preload/Policy.java
+++ b/tools/preload/Policy.java
@@ -24,47 +24,32 @@
public class Policy {
/**
+ * No constructor - use static methods only
+ */
+ private Policy() {}
+
+ /**
* This location (in the build system) of the preloaded-classes file.
*/
- private static final String PRELOADED_CLASS_FILE = "frameworks/base/preloaded-classes";
-
+ private static final String PRELOADED_CLASS_FILE
+ = "frameworks/base/preloaded-classes";
+
/**
- * The internal process name of the system process. Note, this also shows up as
- * "system_process", e.g. in ddms.
- */
- private static final String SYSTEM_SERVER_PROCESS_NAME = "system_server";
-
- /**
- * Names of non-application processes - these will not be checked for preloaded classes.
- *
- * TODO: Replace this hardcoded list with a walk up the parent chain looking for zygote.
- */
- private static final Set<String> NOT_FROM_ZYGOTE = new HashSet<String>(Arrays.asList(
- "zygote",
- "dexopt",
- "unknown",
- SYSTEM_SERVER_PROCESS_NAME,
- "com.android.development",
- "app_process" // am & other shell commands
- ));
-
- /**
- * Long running services. These are restricted in their contribution to the preloader
- * because their launch time is less critical.
+ * Long running services. These are restricted in their contribution to the
+ * preloader because their launch time is less critical.
*/
private static final Set<String> SERVICES = new HashSet<String>(Arrays.asList(
- SYSTEM_SERVER_PROCESS_NAME,
- "com.android.acore",
- // Commented out to make sure DefaultTimeZones gets preloaded.
- // "com.android.phone",
+ "system_server",
"com.google.process.content",
- "android.process.media"
+ "android.process.media",
+ "com.google.process.gapps"
));
/**
* Classes which we shouldn't load from the Zygote.
*/
- private static final Set<String> EXCLUDED_CLASSES = new HashSet<String>(Arrays.asList(
+ private static final Set<String> EXCLUDED_CLASSES
+ = new HashSet<String>(Arrays.asList(
// Binders
"android.app.AlarmManager",
"android.app.SearchManager",
@@ -75,15 +60,9 @@
"android.os.AsyncTask",
"android.pim.ContactsAsyncHelper",
"java.lang.ProcessManager"
-
));
/**
- * No constructor - use static methods only
- */
- private Policy() {}
-
- /**
* Returns the path/file name of the preloaded classes file that will be written
* by WritePreloadedClassFile.
*/
@@ -92,13 +71,6 @@
}
/**
- * Reports if a given process name was created from zygote
- */
- public static boolean isFromZygote(String processName) {
- return !NOT_FROM_ZYGOTE.contains(processName);
- }
-
- /**
* Reports if the given process name is a "long running" process or service
*/
public static boolean isService(String processName) {
diff --git a/tools/preload/PrintCsv.java b/tools/preload/PrintCsv.java
index 9f2a318..62f4271 100644
--- a/tools/preload/PrintCsv.java
+++ b/tools/preload/PrintCsv.java
@@ -18,6 +18,9 @@
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.io.BufferedInputStream;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.TreeSet;
/**
* Prints raw information in CSV format.
@@ -37,13 +40,14 @@
+ ",Preloaded"
+ ",Median Load Time (us)"
+ ",Median Init Time (us)"
+ + ",Process Names"
+ ",Load Count"
- + ",Init Count"
- + ",Managed Heap (B)"
- + ",Native Heap (B)"
- + ",Managed Pages (kB)"
- + ",Native Pages (kB)"
- + ",Other Pages (kB)");
+ + ",Init Count");
+// + ",Managed Heap (B)"
+// + ",Native Heap (B)"
+// + ",Managed Pages (kB)"
+// + ",Native Pages (kB)"
+// + ",Other Pages (kB)");
MemoryUsage baseline = root.baseline;
@@ -60,10 +64,23 @@
System.out.print(',');
System.out.print(loadedClass.medianInitTimeMicros());
System.out.print(',');
+ System.out.print('"');
+
+ Set<String> procNames = new TreeSet<String>();
+ for (Operation op : loadedClass.loads)
+ procNames.add(op.process.name);
+ for (Operation op : loadedClass.initializations)
+ procNames.add(op.process.name);
+ for (String name : procNames) {
+ System.out.print(name + "\n");
+ }
+
+ System.out.print('"');
+ System.out.print(',');
System.out.print(loadedClass.loads.size());
System.out.print(',');
System.out.print(loadedClass.initializations.size());
-
+/*
if (loadedClass.memoryUsage.isAvailable()) {
MemoryUsage subtracted
= loadedClass.memoryUsage.subtract(baseline);
@@ -82,7 +99,7 @@
} else {
System.out.print(",n/a,n/a,n/a,n/a,n/a");
}
-
+*/
System.out.println();
}
}
diff --git a/tools/preload/Proc.java b/tools/preload/Proc.java
index 22697f8..66e04dc 100644
--- a/tools/preload/Proc.java
+++ b/tools/preload/Proc.java
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-import java.util.Set;
-import java.util.HashSet;
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
@@ -23,7 +21,6 @@
import java.util.Map;
import java.util.HashMap;
import java.util.Collections;
-import java.util.TreeSet;
import java.io.Serializable;
/**
@@ -38,11 +35,6 @@
*/
static final int PERCENTAGE_TO_PRELOAD = 75;
- /**
- * Maximum number of classes to preload for a given process.
- */
- static final int MAX_TO_PRELOAD = 100;
-
/** Parent process. */
final Proc parent;
@@ -97,11 +89,9 @@
/**
* Returns a list of classes which should be preloaded.
- *
- * @param takeAllClasses forces all classes to be taken (irrespective of ranking)
*/
- List<LoadedClass> highestRankedClasses(boolean takeAllClasses) {
- if (!isApplication()) {
+ List<LoadedClass> highestRankedClasses() {
+ if (!isApplication() || Policy.isService(this.name)) {
return Collections.emptyList();
}
@@ -114,25 +104,13 @@
int timeToSave = totalTimeMicros() * percentageToPreload() / 100;
int timeSaved = 0;
- boolean service = Policy.isService(this.name);
-
+ int count = 0;
List<LoadedClass> highest = new ArrayList<LoadedClass>();
for (Operation operation : ranked) {
-
- // These are actual ranking decisions, which can be overridden
- if (!takeAllClasses) {
- if (highest.size() >= MAX_TO_PRELOAD) {
- System.out.println(name + " got "
- + (timeSaved * 100 / timeToSave) + "% through");
- break;
- }
-
- if (timeSaved >= timeToSave) {
- break;
- }
+ if (timeSaved >= timeToSave || count++ > 100) {
+ break;
}
- // The remaining rules apply even to wired-down processes
if (!Policy.isPreloadableClass(operation.loadedClass.name)) {
continue;
}
@@ -140,13 +118,8 @@
if (!operation.loadedClass.systemClass) {
continue;
}
-
- // Only load java.* class for services.
- if (!service || operation.loadedClass.name.startsWith("java.")) {
- highest.add(operation.loadedClass);
- }
-
- // For services, still count the time even if it's not in java.*
+
+ highest.add(operation.loadedClass);
timeSaved += operation.medianExclusiveTimeMicros();
}
@@ -166,11 +139,13 @@
/**
* Returns true if this process is an app.
- *
- * TODO: Replace the hardcoded list with a walk up the parent chain looking for zygote.
*/
public boolean isApplication() {
- return Policy.isFromZygote(name);
+ if (name.equals("com.android.development")) {
+ return false;
+ }
+
+ return parent != null && parent.name.equals("zygote");
}
/**
diff --git a/tools/preload/WritePreloadedClassFile.java b/tools/preload/WritePreloadedClassFile.java
index d87b1f0..b209af0 100644
--- a/tools/preload/WritePreloadedClassFile.java
+++ b/tools/preload/WritePreloadedClassFile.java
@@ -20,8 +20,6 @@
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Set;
import java.util.TreeSet;
@@ -32,71 +30,85 @@
public class WritePreloadedClassFile {
public static void main(String[] args) throws IOException, ClassNotFoundException {
-
- // Process command-line arguments first
- List<String> wiredProcesses = new ArrayList<String>();
- String inputFileName = null;
- int argOffset = 0;
- try {
- while ("--preload-all-process".equals(args[argOffset])) {
- argOffset++;
- wiredProcesses.add(args[argOffset++]);
- }
-
- inputFileName = args[argOffset++];
- } catch (RuntimeException e) {
- System.err.println("Usage: WritePreloadedClassFile " +
- "[--preload-all-process process-name] " +
- "[compiled log file]");
- System.exit(0);
+ if (args.length != 1) {
+ System.err.println("Usage: WritePreloadedClassFile [compiled log]");
+ System.exit(-1);
}
+ String rootFile = args[0];
+ Root root = Root.fromFile(rootFile);
- Root root = Root.fromFile(inputFileName);
-
+ // No classes are preloaded to start.
for (LoadedClass loadedClass : root.loadedClasses.values()) {
loadedClass.preloaded = false;
}
+ // Open preloaded-classes file for output.
Writer out = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(Policy.getPreloadedClassFileName()),
Charset.forName("US-ASCII")));
out.write("# Classes which are preloaded by com.android.internal.os.ZygoteInit.\n");
out.write("# Automatically generated by /frameworks/base/tools/preload.\n");
- out.write("# percent=" + Proc.PERCENTAGE_TO_PRELOAD + ", weight="
- + ClassRank.SEQUENCE_WEIGHT
+ out.write("# percent=" + Proc.PERCENTAGE_TO_PRELOAD
+ + ", weight=" + ClassRank.SEQUENCE_WEIGHT
+ ", bucket_size=" + ClassRank.BUCKET_SIZE
+ "\n");
- for (String wiredProcess : wiredProcesses) {
- out.write("# forcing classes loaded by: " + wiredProcess + "\n");
- }
- Set<LoadedClass> highestRanked = new TreeSet<LoadedClass>();
- for (Proc proc : root.processes.values()) {
- // test to see if this is one of the wired-down ("take all classes") processes
- boolean isWired = wiredProcesses.contains(proc.name);
-
- List<LoadedClass> highestForProc = proc.highestRankedClasses(isWired);
+ Set<LoadedClass> toPreload = new TreeSet<LoadedClass>();
- System.out.println(proc.name + ": " + highestForProc.size());
-
- for (LoadedClass loadedClass : highestForProc) {
- loadedClass.preloaded = true;
+ // Preload all classes that were loaded by at least 2 apps, if both
+ // apps run at the same time, they'll share memory.
+ for (LoadedClass loadedClass : root.loadedClasses.values()) {
+ if (!loadedClass.isPreloadable()) {
+ continue;
}
- highestRanked.addAll(highestForProc);
+
+ Set<String> appNames = loadedClass.applicationNames();
+
+ if (appNames.size() > 3) {
+ toPreload.add(loadedClass);
+ }
}
- for (LoadedClass loadedClass : highestRanked) {
+ // Try to make individual apps start faster by preloading slowest
+ // classes.
+ for (Proc proc : root.processes.values()) {
+ toPreload.addAll(proc.highestRankedClasses());
+ }
+
+ System.out.println(toPreload.size() + " classes will be preloaded.");
+
+ // Make classes that were already loaded by the zygote explicit.
+ // This adds minimal overhead but avoid confusion about classes not
+ // appearing in the list.
+ addAllClassesFor("zygote", root, toPreload);
+
+ for (LoadedClass loadedClass : toPreload) {
out.write(loadedClass.name);
out.write('\n');
}
out.close();
- System.out.println(highestRanked.size()
- + " classes will be preloaded.");
-
// Update data to reflect LoadedClass.preloaded changes.
- root.toFile(inputFileName);
+ for (LoadedClass loadedClass : toPreload) {
+ loadedClass.preloaded = true;
+ }
+ root.toFile(rootFile);
+ }
+
+ private static void addAllClassesFor(String packageName, Root root,
+ Set<LoadedClass> toPreload) {
+ for (Proc proc : root.processes.values()) {
+ if (proc.name.equals(packageName)) {
+ for (Operation operation : proc.operations) {
+ // TODO: I'm not sure how the zygote loaded classes that
+ // aren't supposed to be preloadable...
+ if (operation.loadedClass.isPreloadable()) {
+ toPreload.add(operation.loadedClass);
+ }
+ }
+ }
+ }
}
}
diff --git a/tools/preload/preload.iml b/tools/preload/preload.iml
index d1fab57..2d87c55 100644
--- a/tools/preload/preload.iml
+++ b/tools/preload/preload.iml
@@ -1,15 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<module relativePaths="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="false">
- <output url="file:///tmp/preload/" />
+ <output url="file:///tmp/preload" />
+ <output-test url="file:///tmp/preload" />
<exclude-output />
- <output-test url="file:///tmp/preload/" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
- <orderEntryProperties />
</component>
</module>
diff --git a/tools/preload/preload.ipr b/tools/preload/preload.ipr
index c5613ad..f78bf76 100644
--- a/tools/preload/preload.ipr
+++ b/tools/preload/preload.ipr
@@ -114,6 +114,7 @@
<option name="ADDITIONAL_OPTIONS_STRING" value="" />
<option name="MAXIMUM_HEAP_SIZE" value="128" />
</component>
+ <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
<component name="EntryPointsManager">
<entry_points version="2.0" />
</component>
@@ -125,13 +126,13 @@
<component name="IdProvider" IDEtalkID="D171F99B9178C1675593DC9A76A5CC7E" />
<component name="InspectionProjectProfileManager">
<option name="PROJECT_PROFILE" value="Project Default" />
- <option name="USE_PROJECT_LEVEL_SETTINGS" value="false" />
- <scopes />
+ <option name="USE_PROJECT_PROFILE" value="true" />
+ <version value="1.0" />
<profiles>
<profile version="1.0" is_locked="false">
<option name="myName" value="Project Default" />
<option name="myLocal" value="false" />
- <inspection_tool class="JavaDoc" level="WARNING" enabled="false">
+ <inspection_tool class="JavaDoc" enabled="false" level="WARNING" enabled_by_default="false">
<option name="TOP_LEVEL_CLASS_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
@@ -160,14 +161,19 @@
<option name="IGNORE_JAVADOC_PERIOD" value="true" />
<option name="myAdditionalJavadocTags" value="" />
</inspection_tool>
- <inspection_tool class="OnDemandImport" level="WARNING" enabled="true" />
- <inspection_tool class="SamePackageImport" level="WARNING" enabled="true" />
- <inspection_tool class="JavaLangImport" level="WARNING" enabled="true" />
- <inspection_tool class="RedundantImport" level="WARNING" enabled="true" />
- <inspection_tool class="UnusedImport" level="WARNING" enabled="true" />
+ <inspection_tool class="JavaLangImport" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="OnDemandImport" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="RedundantImport" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="SamePackageImport" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="UnusedImport" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</profiles>
- <list size="0" />
+ <list size="4">
+ <item index="0" class="java.lang.String" itemvalue="WARNING" />
+ <item index="1" class="java.lang.String" itemvalue="SERVER PROBLEM" />
+ <item index="2" class="java.lang.String" itemvalue="INFO" />
+ <item index="3" class="java.lang.String" itemvalue="ERROR" />
+ </list>
</component>
<component name="JavacSettings">
<option name="DEBUGGING_INFO" value="true" />
@@ -332,13 +338,19 @@
<option name="USE_CLIENT_FILTER" value="true" />
<option name="CLIENT" value="" />
</component>
+ <component name="ProjectDetails">
+ <option name="projectName" value="preload" />
+ </component>
<component name="ProjectFileVersion" converted="true" />
+ <component name="ProjectKey">
+ <option name="state" value="project:///Volumes/Android/donut/frameworks/base/tools/preload/preload.ipr" />
+ </component>
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/preload.iml" filepath="$PROJECT_DIR$/preload.iml" />
</modules>
</component>
- <component name="ProjectRootManager" version="2" assert-keyword="true" jdk-15="true" project-jdk-name="1.5" project-jdk-type="JavaSDK">
+ <component name="ProjectRootManager" version="2" languageLevel="JDK_1_5" assert-keyword="true" jdk-15="true" project-jdk-name="1.5" project-jdk-type="JavaSDK">
<output url="file:///tmp/preload" />
</component>
<component name="RmicSettings">
@@ -374,6 +386,9 @@
<option name="myValidatorValidationEnabled" value="true" />
<option name="myReportErrorsAsWarnings" value="true" />
</component>
+ <component name="SvnBranchConfigurationManager">
+ <option name="mySupportsUserInfoFilter" value="true" />
+ </component>
<component name="SvnChangesBrowserSettings">
<option name="USE_AUTHOR_FIELD" value="true" />
<option name="AUTHOR" value="" />
@@ -381,15 +396,6 @@
<option name="USE_PROJECT_SETTINGS" value="true" />
<option name="USE_ALTERNATE_LOCATION" value="false" />
</component>
- <component name="SvnConfiguration">
- <option name="USER" value="" />
- <option name="PASSWORD" value="" />
- <option name="PROCESS_UNRESOLVED" value="false" />
- <option name="LAST_MERGED_REVISION" />
- <option name="UPDATE_RUN_STATUS" value="false" />
- <option name="UPDATE_RECURSIVELY" value="true" />
- <option name="MERGE_DRY_RUN" value="false" />
- </component>
<component name="VCS.FileViewConfiguration">
<option name="SELECTED_STATUSES" value="DEFAULT" />
<option name="SELECTED_COLUMNS" value="DEFAULT" />