diff options
36 files changed, 506 insertions, 736 deletions
diff --git a/api/current.txt b/api/current.txt index d79230e..51c9348 100644 --- a/api/current.txt +++ b/api/current.txt @@ -628,6 +628,8 @@ package android { field public static final int listDividerAlertDialog = 16843525; // 0x1010305 field public static final int listPopupWindowStyle = 16843519; // 0x10102ff field public static final int listPreferredItemHeight = 16842829; // 0x101004d + field public static final int listPreferredItemHeightLarge = 16843670; // 0x1010396 + field public static final int listPreferredItemHeightSmall = 16843671; // 0x1010397 field public static final int listSelector = 16843003; // 0x10100fb field public static final int listSeparatorTextViewStyle = 16843272; // 0x1010208 field public static final int listViewStyle = 16842868; // 0x1010074 @@ -5808,6 +5810,7 @@ package android.content.pm { method public abstract void setInstallerPackageName(java.lang.String, java.lang.String); field public static final int COMPONENT_ENABLED_STATE_DEFAULT = 0; // 0x0 field public static final int COMPONENT_ENABLED_STATE_DISABLED = 2; // 0x2 + field public static final int COMPONENT_ENABLED_STATE_DISABLED_USER = 3; // 0x3 field public static final int COMPONENT_ENABLED_STATE_ENABLED = 1; // 0x1 field public static final int DONT_KILL_APP = 1; // 0x1 field public static final java.lang.String FEATURE_AUDIO_LOW_LATENCY = "android.hardware.audio.low_latency"; @@ -16688,6 +16691,7 @@ package android.renderscript { method public static android.renderscript.Element U8_4(android.renderscript.RenderScript); method public static android.renderscript.Element createPixel(android.renderscript.RenderScript, android.renderscript.Element.DataType, android.renderscript.Element.DataKind); method public static android.renderscript.Element createVector(android.renderscript.RenderScript, android.renderscript.Element.DataType, int); + method public boolean isCompatible(android.renderscript.Element); method public boolean isComplex(); } @@ -17386,9 +17390,12 @@ package android.renderscript { enum_constant public static final android.renderscript.Type.CubemapFace NEGATIVE_X; enum_constant public static final android.renderscript.Type.CubemapFace NEGATIVE_Y; enum_constant public static final android.renderscript.Type.CubemapFace NEGATIVE_Z; - enum_constant public static final android.renderscript.Type.CubemapFace POSITVE_X; - enum_constant public static final android.renderscript.Type.CubemapFace POSITVE_Y; - enum_constant public static final android.renderscript.Type.CubemapFace POSITVE_Z; + enum_constant public static final android.renderscript.Type.CubemapFace POSITIVE_X; + enum_constant public static final android.renderscript.Type.CubemapFace POSITIVE_Y; + enum_constant public static final android.renderscript.Type.CubemapFace POSITIVE_Z; + enum_constant public static final deprecated android.renderscript.Type.CubemapFace POSITVE_X; + enum_constant public static final deprecated android.renderscript.Type.CubemapFace POSITVE_Y; + enum_constant public static final deprecated android.renderscript.Type.CubemapFace POSITVE_Z; } } diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java index b0e4a86..e433079 100644 --- a/cmds/pm/src/com/android/commands/pm/Pm.java +++ b/cmds/pm/src/com/android/commands/pm/Pm.java @@ -120,6 +120,11 @@ public final class Pm { return; } + if ("disable-user".equals(op)) { + runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER); + return; + } + if ("setInstallLocation".equals(op)) { runSetInstallLocation(); return; @@ -970,6 +975,8 @@ public final class Pm { return "enabled"; case PackageManager.COMPONENT_ENABLED_STATE_DISABLED: return "disabled"; + case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER: + return "disabled-user"; } return "unknown"; } diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index c0a1d8e..454cb31 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -417,6 +417,12 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { public boolean enabled = true; /** + * For convenient access to the current enabled setting of this app. + * @hide + */ + public int enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; + + /** * For convenient access to package's install location. * @hide */ @@ -508,6 +514,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { uid = orig.uid; targetSdkVersion = orig.targetSdkVersion; enabled = orig.enabled; + enabledSetting = orig.enabledSetting; installLocation = orig.installLocation; manageSpaceActivityName = orig.manageSpaceActivityName; descriptionRes = orig.descriptionRes; @@ -544,6 +551,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { dest.writeInt(uid); dest.writeInt(targetSdkVersion); dest.writeInt(enabled ? 1 : 0); + dest.writeInt(enabledSetting); dest.writeInt(installLocation); dest.writeString(manageSpaceActivityName); dest.writeString(backupAgentName); @@ -581,6 +589,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { uid = source.readInt(); targetSdkVersion = source.readInt(); enabled = source.readInt() != 0; + enabledSetting = source.readInt(); installLocation = source.readInt(); manageSpaceActivityName = source.readString(); backupAgentName = source.readString(); diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 1cd8ec0..dd684cd 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -224,11 +224,41 @@ public abstract class PackageManager { */ public static final int SIGNATURE_UNKNOWN_PACKAGE = -4; + /** + * Flag for {@link #setApplicationEnabledSetting(String, int, int)} + * and {@link #setComponentEnabledSetting(ComponentName, int, int)}: This + * component or application is in its default enabled state (as specified + * in its manifest). + */ public static final int COMPONENT_ENABLED_STATE_DEFAULT = 0; + + /** + * Flag for {@link #setApplicationEnabledSetting(String, int, int)} + * and {@link #setComponentEnabledSetting(ComponentName, int, int)}: This + * component or application has been explictily enabled, regardless of + * what it has specified in its manifest. + */ public static final int COMPONENT_ENABLED_STATE_ENABLED = 1; + + /** + * Flag for {@link #setApplicationEnabledSetting(String, int, int)} + * and {@link #setComponentEnabledSetting(ComponentName, int, int)}: This + * component or application has been explicitly disabled, regardless of + * what it has specified in its manifest. + */ public static final int COMPONENT_ENABLED_STATE_DISABLED = 2; /** + * Flag for {@link #setApplicationEnabledSetting(String, int, int)} only: The + * user has explicitly disabled the application, regardless of what it has + * specified in its manifest. Because this is due to the user's request, + * they may re-enable it if desired through the appropriate system UI. This + * option currently <strong>can not</strong> be used with + * {@link #setComponentEnabledSetting(ComponentName, int, int)}. + */ + public static final int COMPONENT_ENABLED_STATE_DISABLED_USER = 3; + + /** * Flag parameter for {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} to * indicate that this package should be installed as forward locked, i.e. only the app itself * should have access to its code and non-resource assets. diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 31ad6e9..e927f6c 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -3128,9 +3128,11 @@ public class PackageParser { } if (p.mSetEnabled == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { ai.enabled = true; - } else if (p.mSetEnabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) { + } else if (p.mSetEnabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED + || p.mSetEnabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) { ai.enabled = false; } + ai.enabledSetting = p.mSetEnabled; return ai; } diff --git a/core/java/android/provider/CalendarContract.java b/core/java/android/provider/CalendarContract.java index 17b1031..4368e31 100644 --- a/core/java/android/provider/CalendarContract.java +++ b/core/java/android/provider/CalendarContract.java @@ -476,7 +476,96 @@ public final class CalendarContract { } /** - * Fields and helpers for interacting with Calendars. + * Constants and helpers for the Calendars table, which contains details for + * individual calendars. <h3>Operations</h3> All operations can be done + * either as an app or as a sync adapter. To perform an operation as a sync + * adapter {@link #CALLER_IS_SYNCADAPTER} should be set to true and + * {@link #ACCOUNT_NAME} and {@link #ACCOUNT_TYPE} must be set in the Uri + * parameters. See + * {@link Uri.Builder#appendQueryParameter(java.lang.String, java.lang.String)} + * for details on adding parameters. Sync adapters have write access to more + * columns but are restricted to a single account at a time. Calendars are + * designed to be primarily managed by a sync adapter and inserting new + * calendars should be done as a sync adapter. For the most part, apps + * should only update calendars (such as changing the color or display + * name). If a local calendar is required an app can do so by inserting as a + * sync adapter and using an {@link #ACCOUNT_TYPE} of + * {@link #ACCOUNT_TYPE_LOCAL} . + * <dl> + * <dt><b>Insert</b></dt> + * <dd>When inserting a new calendar the following fields must be included: + * <ul> + * <li>{@link #ACCOUNT_NAME}</li> + * <li>{@link #ACCOUNT_TYPE}</li> + * <li>{@link #NAME}</li> + * <li>{@link #CALENDAR_DISPLAY_NAME}</li> + * <li>{@link #CALENDAR_COLOR}</li> + * <li>{@link #CALENDAR_ACCESS_LEVEL}</li> + * <li>{@link #OWNER_ACCOUNT}</li> + * </ul> + * The following fields are not required when inserting a Calendar but are + * generally a good idea to include: + * <ul> + * <li>{@link #SYNC_EVENTS} set to 1</li> + * <li>{@link #CALENDAR_TIME_ZONE}</li> + * <li>{@link #ALLOWED_REMINDERS}</li> + * </ul> + * <dt><b>Update</b></dt> + * <dd>To perform an update on a calendar the {@link #_ID} of the calendar + * should be provided either as an appended id to the Uri ( + * {@link ContentUris#withAppendedId}) or as the first selection item--the + * selection should start with "_id=?" and the first selectionArg should be + * the _id of the calendar. Calendars may also be updated using a selection + * without the id. In general, the {@link #ACCOUNT_NAME} and + * {@link #ACCOUNT_TYPE} should not be changed after a calendar is created + * as this can cause issues for sync adapters. + * <dt><b>Delete</b></dt> + * <dd>Calendars can be deleted either by the {@link #_ID} as an appended id + * on the Uri or using any standard selection. Deleting a calendar should + * generally be handled by a sync adapter as it will remove the calendar + * from the database and all associated data (aka events).</dd> + * <dt><b>Query</b></dt> + * <dd>Querying the Calendars table will get you all information about a set + * of calendars. There will be one row returned for each calendar that + * matches the query selection, or at most a single row if the {@link #_ID} + * is appended to the Uri.</dd> + * </dl> + * <h3>Calendar Columns</h3> The following Calendar columns are writable by + * both an app and a sync adapter. + * <ul> + * <li>{@link #NAME}</li> + * <li>{@link #CALENDAR_DISPLAY_NAME}</li> + * <li>{@link #CALENDAR_COLOR}</li> + * <li>{@link #VISIBLE}</li> + * <li>{@link #SYNC_EVENTS}</li> + * </ul> + * The following Calendars columns are writable only by a sync adapter + * <ul> + * <li>{@link #ACCOUNT_NAME}</li> + * <li>{@link #ACCOUNT_TYPE}</li> + * <li>{@link #_SYNC_ID}</li> + * <li>{@link #DIRTY}</li> + * <li>{@link #OWNER_ACCOUNT}</li> + * <li>{@link #MAX_REMINDERS}</li> + * <li>{@link #ALLOWED_REMINDERS}</li> + * <li>{@link #CAN_MODIFY_TIME_ZONE}</li> + * <li>{@link #CAN_ORGANIZER_RESPOND}</li> + * <li>{@link #CAN_PARTIALLY_UPDATE}</li> + * <li>{@link #CALENDAR_LOCATION}</li> + * <li>{@link #CALENDAR_TIME_ZONE}</li> + * <li>{@link #CALENDAR_ACCESS_LEVEL}</li> + * <li>{@link #DELETED}</li> + * <li>{@link #CAL_SYNC1}</li> + * <li>{@link #CAL_SYNC2}</li> + * <li>{@link #CAL_SYNC3}</li> + * <li>{@link #CAL_SYNC4}</li> + * <li>{@link #CAL_SYNC5}</li> + * <li>{@link #CAL_SYNC6}</li> + * <li>{@link #CAL_SYNC7}</li> + * <li>{@link #CAL_SYNC8}</li> + * <li>{@link #CAL_SYNC9}</li> + * <li>{@link #CAL_SYNC10}</li> + * </ul> */ public static class Calendars implements BaseColumns, SyncColumns, CalendarsColumns { private static final String WHERE_DELETE_FOR_ACCOUNT = Calendars.ACCOUNT_NAME + "=?" @@ -569,6 +658,7 @@ public final class CalendarContract { DIRTY, OWNER_ACCOUNT, MAX_REMINDERS, + ALLOWED_REMINDERS, CAN_MODIFY_TIME_ZONE, CAN_ORGANIZER_RESPOND, CAN_PARTIALLY_UPDATE, @@ -1252,13 +1342,15 @@ public final class CalendarContract { } /** - * Constants and helpers for the Events table, which contains details of a - * single event. <h3>Operations</h3> All operations can be done either as an - * app or as a sync adapter. To perform an operation as a sync adapter - * {@link #CALLER_IS_SYNCADAPTER} should be set to true in the Uri - * parameters and {@link #ACCOUNT_NAME} and {@link #ACCOUNT_TYPE} must be - * set. Sync adapters have write access to more columns but are restricted - * to a single account at a time. + * Constants and helpers for the Events table, which contains details for + * individual events. <h3>Operations</h3> All operations can be done either + * as an app or as a sync adapter. To perform an operation as a sync adapter + * {@link #CALLER_IS_SYNCADAPTER} should be set to true and + * {@link #ACCOUNT_NAME} and {@link #ACCOUNT_TYPE} must be set in the Uri + * parameters. See + * {@link Uri.Builder#appendQueryParameter(java.lang.String, java.lang.String)} + * for details on adding parameters. Sync adapters have write access to more + * columns but are restricted to a single account at a time. * <dl> * <dt><b>Insert</b></dt> * <dd>When inserting a new event the following fields must be included: @@ -1270,13 +1362,14 @@ public final class CalendarContract { * There are also further requirements when inserting or updating an event. * See the section on Writing to Events.</dd> * <dt><b>Update</b></dt> - * <dd>To perform an update on an Event the {@link Events#_ID} of the event - * must be provided either as an appended id to the Uri ( + * <dd>To perform an update of an Event the {@link Events#_ID} of the event + * should be provided either as an appended id to the Uri ( * {@link ContentUris#withAppendedId}) or as the first selection item--the * selection should start with "_id=?" and the first selectionArg should be - * the _id of the event. Updating an event must respect the same rules as - * inserting and is further restricted in the fields that can be written. - * See the section on Writing to Events.</dd> + * the _id of the event. Updates may also be done using a selection and no + * id. Updating an event must respect the same rules as inserting and is + * further restricted in the fields that can be written. See the section on + * Writing to Events.</dd> * <dt><b>Delete</b></dt> * <dd>Events can be deleted either by the {@link Events#_ID} as an appended * id on the Uri or using any standard selection. If an appended id is used diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index b0e651a..888f0c0 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -6089,7 +6089,11 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit /* Check if the VISIBLE bit has changed */ if ((changed & INVISIBLE) != 0) { needGlobalAttributesUpdate(false); - invalidate(true); + /* + * If this view is becoming invisible, set the DRAWN flag so that + * the next invalidate() will not be skipped. + */ + mPrivateFlags |= DRAWN; if (((mViewFlags & VISIBILITY_MASK) == INVISIBLE) && hasFocus()) { // root view becoming invisible shouldn't clear focus @@ -8736,6 +8740,10 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit } jumpDrawablesToCurrentState(); resolveLayoutDirection(); + if (isFocused()) { + InputMethodManager imm = InputMethodManager.peekInstance(); + imm.focusIn(this); + } } /** @@ -11701,7 +11709,7 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit /** * Utility to return a default size. Uses the supplied size if the - * MeasureSpec imposed no contraints. Will get larger if allowed + * MeasureSpec imposed no constraints. Will get larger if allowed * by the MeasureSpec. * * @param size Default size for this view @@ -11711,7 +11719,7 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit public static int getDefaultSize(int size, int measureSpec) { int result = size; int specMode = MeasureSpec.getMode(measureSpec); - int specSize = MeasureSpec.getSize(measureSpec); + int specSize = MeasureSpec.getSize(measureSpec); switch (specMode) { case MeasureSpec.UNSPECIFIED: diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java index a15ca0c..4a514bf 100644 --- a/core/java/android/widget/GridLayout.java +++ b/core/java/android/widget/GridLayout.java @@ -38,8 +38,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import static android.view.View.MeasureSpec.EXACTLY; -import static android.view.View.MeasureSpec.UNSPECIFIED; import static java.lang.Math.max; import static java.lang.Math.min; @@ -760,43 +758,6 @@ public class GridLayout extends ViewGroup { // Measurement - private static int getChildMeasureSpec2(int spec, int padding, int childDimension) { - int resultSize; - int resultMode; - - if (childDimension >= 0) { - resultSize = childDimension; - resultMode = EXACTLY; - } else { - /* - using the following lines would replicate the logic of ViewGroup.getChildMeasureSpec() - - int specMode = MeasureSpec.getMode(spec); - int specSize = MeasureSpec.getSize(spec); - int size = Math.max(0, specSize - padding); - - resultSize = size; - resultMode = (specMode == EXACTLY && childDimension == LayoutParams.WRAP_CONTENT) ? - AT_MOST : specMode; - */ - resultSize = 0; - resultMode = UNSPECIFIED; - } - return MeasureSpec.makeMeasureSpec(resultSize, resultMode); - } - - @Override - protected void measureChild(View child, int parentWidthSpec, int parentHeightSpec) { - ViewGroup.LayoutParams lp = child.getLayoutParams(); - - int childWidthMeasureSpec = getChildMeasureSpec2(parentWidthSpec, - mPaddingLeft + mPaddingRight, lp.width); - int childHeightMeasureSpec = getChildMeasureSpec2(parentHeightSpec, - mPaddingTop + mPaddingBottom, lp.height); - - child.measure(childWidthMeasureSpec, childHeightMeasureSpec); - } - @Override protected void onMeasure(int widthSpec, int heightSpec) { measureChildren(widthSpec, heightSpec); @@ -1145,9 +1106,6 @@ public class GridLayout extends ViewGroup { return result; } - /* - Topological sort. - */ private Arc[] topologicalSort(final Arc[] arcs, int start) { // todo ensure the <start> vertex is added in edge cases final List<Arc> result = new ArrayList<Arc>(); @@ -2214,7 +2172,9 @@ public class GridLayout extends ViewGroup { * * @param view the view to which this alignment should be applied * @param viewSize the measured size of the view - * @param measurementType the type of measurement that should be made + * @param measurementType The type of measurement that should be made. This feature + * is currently unused as GridLayout only supports one + * type of measurement: {@link View#measure(int, int)}. * * @return the alignment value */ @@ -2230,7 +2190,9 @@ public class GridLayout extends ViewGroup { * @param view the view to which this alignment should be applied * @param viewSize the measured size of the view * @param cellSize the size of the cell into which this view will be placed - * @param measurementType the type of measurement that should be made + * @param measurementType The type of measurement that should be made. This feature + * is currently unused as GridLayout only supports one + * type of measurement: {@link View#measure(int, int)}. * * @return the aligned size */ diff --git a/core/java/android/widget/Space.java b/core/java/android/widget/Space.java index d98b937..d7b2ec2 100644 --- a/core/java/android/widget/Space.java +++ b/core/java/android/widget/Space.java @@ -72,4 +72,35 @@ public final class Space extends View { public void setLayoutParams(ViewGroup.LayoutParams params) { super.setLayoutParams(params); } + + /** + * Compare to: {@link View#getDefaultSize(int, int)} + * If mode is AT_MOST, return the child size instead of the parent size + * (unless it is too big). + */ + private static int getDefaultSize2(int size, int measureSpec) { + int result = size; + int specMode = MeasureSpec.getMode(measureSpec); + int specSize = MeasureSpec.getSize(measureSpec); + + switch (specMode) { + case MeasureSpec.UNSPECIFIED: + result = size; + break; + case MeasureSpec.AT_MOST: + result = Math.min(size, specSize); + break; + case MeasureSpec.EXACTLY: + result = specSize; + break; + } + return result; + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + setMeasuredDimension( + getDefaultSize2(getSuggestedMinimumWidth(), widthMeasureSpec), + getDefaultSize2(getSuggestedMinimumHeight(), heightMeasureSpec)); + } } diff --git a/core/java/com/android/internal/net/VpnConfig.java b/core/java/com/android/internal/net/VpnConfig.java index 18d9ec4..773be5b 100644 --- a/core/java/com/android/internal/net/VpnConfig.java +++ b/core/java/com/android/internal/net/VpnConfig.java @@ -16,8 +16,12 @@ package com.android.internal.net; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; import android.os.Parcel; import android.os.Parcelable; +import android.os.SystemClock; /** * A simple container used to carry information in VpnBuilder, VpnDialogs, @@ -27,6 +31,30 @@ import android.os.Parcelable; */ public class VpnConfig implements Parcelable { + public static final String ACTION_VPN_REVOKED = "android.net.vpn.action.REVOKED"; + + public static void enforceCallingPackage(String packageName) { + if (!"com.android.vpndialogs".equals(packageName)) { + throw new SecurityException("Unauthorized Caller"); + } + } + + public static Intent getIntentForConfirmation() { + Intent intent = new Intent(); + intent.setClassName("com.android.vpndialogs", "com.android.vpndialogs.ConfirmDialog"); + return intent; + } + + public static PendingIntent getIntentForNotification(Context context, VpnConfig config) { + config.startTime = SystemClock.elapsedRealtime(); + Intent intent = new Intent(); + intent.setClassName("com.android.vpndialogs", "com.android.vpndialogs.ManageDialog"); + intent.putExtra("config", config); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY | + Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); + return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); + } + public String packageName; public String sessionName; public String interfaceName; diff --git a/core/java/com/android/internal/util/HanziToPinyin.java b/core/java/com/android/internal/util/HanziToPinyin.java deleted file mode 100644 index 6a4adaa..0000000 --- a/core/java/com/android/internal/util/HanziToPinyin.java +++ /dev/null @@ -1,495 +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.internal.util; - -import android.text.TextUtils; -import android.util.Log; - -import java.text.Collator; -import java.util.ArrayList; -import java.util.Locale; - -/** - * An object to convert Chinese character to its corresponding pinyin string. - * For characters with multiple possible pinyin string, only one is selected - * according to collator. Polyphone is not supported in this implementation. - * This class is implemented to achieve the best runtime performance and minimum - * runtime resources with tolerable sacrifice of accuracy. This implementation - * highly depends on zh_CN ICU collation data and must be always synchronized with - * ICU. - */ -public class HanziToPinyin { - private static final String TAG = "HanziToPinyin"; - - private static final char[] UNIHANS = { - '\u5416', '\u54ce', '\u5b89', '\u80ae', '\u51f9', '\u516b', '\u63b0', '\u6273', - '\u90a6', '\u52f9', '\u9642', '\u5954', '\u4f3b', '\u7680', '\u782d', '\u706c', - '\u618b', '\u6c43', '\u51ab', '\u7676', '\u5cec', '\u5693', '\u5072', '\u53c2', - '\u4ed3', '\u64a1', '\u518a', '\u5d7e', '\u564c', '\u6260', '\u62c6', '\u8fbf', - '\u4f25', '\u6284', '\u8f66', '\u62bb', '\u9637', '\u5403', '\u5145', '\u62bd', - '\u51fa', '\u640b', '\u5ddb', '\u5205', '\u5439', '\u65fe', '\u8e14', '\u5472', - '\u4ece', '\u51d1', '\u7c97', '\u6c46', '\u5d14', '\u90a8', '\u6413', '\u5491', - '\u5446', '\u4e39', '\u5f53', '\u5200', '\u6074', '\u6265', '\u706f', '\u4efe', - '\u55f2', '\u6541', '\u5201', '\u7239', '\u4e01', '\u4e1f', '\u4e1c', '\u543a', - '\u5262', '\u8011', '\u5796', '\u5428', '\u591a', '\u59b8', '\u5940', '\u97a5', - '\u800c', '\u53d1', '\u5e06', '\u531a', '\u98de', '\u5206', '\u4e30', '\u8985', - '\u4ecf', '\u57ba', '\u7d11', '\u592b', '\u7324', '\u65ee', '\u4f85', '\u5e72', - '\u5188', '\u768b', '\u6208', '\u7ed9', '\u6839', '\u63ef', '\u55bc', '\u55f0', - '\u5de5', '\u52fe', '\u4f30', '\u9e39', '\u4e56', '\u5173', '\u5149', '\u5f52', - '\u4e28', '\u8b34', '\u5459', '\u598e', '\u548d', '\u4f44', '\u592f', '\u8320', - '\u8bc3', '\u9ed2', '\u62eb', '\u4ea8', '\u53ff', '\u9f41', '\u4e4e', '\u82b1', - '\u6000', '\u6b22', '\u5ddf', '\u7070', '\u660f', '\u5419', '\u4e0c', '\u52a0', - '\u620b', '\u6c5f', '\u827d', '\u9636', '\u5dfe', '\u5755', '\u5182', '\u4e29', - '\u51e5', '\u59e2', '\u5658', '\u519b', '\u5494', '\u5f00', '\u938e', '\u5ffc', - '\u5c3b', '\u533c', '\u808e', '\u52a5', '\u7a7a', '\u62a0', '\u625d', '\u5938', - '\u84af', '\u5bbd', '\u5321', '\u4e8f', '\u5764', '\u6269', '\u62c9', '\u4f86', - '\u5170', '\u5577', '\u635e', '\u4ec2', '\u96f7', '\u8137', '\u68f1', '\u695e', - '\u550e', '\u4fe9', '\u5afe', '\u826f', '\u8e7d', '\u57d3', '\u53b8', '\u62ce', - '\u6e9c', '\u9f99', '\u5a04', '\u565c', '\u5b6a', '\u62a1', '\u9831', '\u5988', - '\u57cb', '\u989f', '\u7264', '\u732b', '\u5445', '\u95e8', '\u6c13', '\u54aa', - '\u5b80', '\u55b5', '\u4e5c', '\u6c11', '\u540d', '\u8c2c', '\u6478', '\u725f', - '\u6bcd', '\u62cf', '\u8149', '\u56e1', '\u56d4', '\u5b6c', '\u8bb7', '\u5a1e', - '\u5ae9', '\u80fd', '\u92b0', '\u62c8', '\u5a18', '\u9e1f', '\u634f', '\u56dc', - '\u5b81', '\u599e', '\u519c', '\u7fba', '\u5974', '\u597b', '\u9ec1', '\u90cd', - '\u5662', '\u8bb4', '\u5991', '\u62cd', '\u7705', '\u6c78', '\u629b', '\u5478', - '\u55b7', '\u5309', '\u4e76', '\u7247', '\u527d', '\u6c15', '\u59d8', '\u4e52', - '\u948b', '\u5256', '\u4ec6', '\u4e03', '\u6390', '\u5343', '\u545b', '\u6084', - '\u5207', '\u4eb2', '\u9751', '\u5b86', '\u74d7', '\u533a', '\u5cd1', '\u7094', - '\u590b', '\u5465', '\u7a63', '\u835b', '\u60f9', '\u4eba', '\u6254', '\u65e5', - '\u620e', '\u53b9', '\u909a', '\u5827', '\u6875', '\u95f0', '\u633c', '\u4ee8', - '\u6be2', '\u4e09', '\u6852', '\u63bb', '\u8272', '\u68ee', '\u50e7', '\u6740', - '\u7b5b', '\u5c71', '\u4f24', '\u5f30', '\u5962', '\u7533', '\u5347', '\u5c38', - '\u53ce', '\u4e66', '\u5237', '\u8870', '\u95e9', '\u53cc', '\u8c01', '\u542e', - '\u8bf4', '\u53b6', '\u5fea', '\u51c1', '\u82cf', '\u72fb', '\u590a', '\u5b59', - '\u5506', '\u4ed6', '\u5b61', '\u574d', '\u6c64', '\u5932', '\u5fd1', '\u81af', - '\u5254', '\u5929', '\u65eb', '\u6017', '\u5385', '\u70b5', '\u5077', '\u51f8', - '\u6e4d', '\u63a8', '\u541e', '\u8bac', '\u52b8', '\u6b6a', '\u5f2f', '\u5c23', - '\u5371', '\u6637', '\u7fc1', '\u631d', '\u4e4c', '\u5915', '\u5477', '\u4ed9', - '\u4e61', '\u7071', '\u4e9b', '\u5fc3', '\u5174', '\u51f6', '\u4f11', '\u620c', - '\u5405', '\u75b6', '\u7025', '\u4e2b', '\u54bd', '\u592e', '\u5e7a', '\u503b', - '\u4e00', '\u4e5a', '\u5e94', '\u5537', '\u4f63', '\u4f18', '\u7ea1', '\u56e6', - '\u66f0', '\u8480', '\u5e00', '\u707d', '\u5142', '\u7242', '\u50ae', '\u556b', - '\u9c61', '\u600e', '\u66fd', '\u5412', '\u635a', '\u6cbe', '\u5f20', '\u4f4b', - '\u8707', '\u8d1e', '\u9eee', '\u4e4b', '\u4e2d', '\u5dde', '\u6731', '\u6293', - '\u62fd', '\u4e13', '\u5986', '\u96b9', '\u5b92', '\u5353', '\u4ed4', '\u5b97', - '\u90b9', '\u79df', '\u5297', '\u55fa', '\u5c0a', '\u6628', - }; - private final static byte[][] PINYINS = { - {65, 00, 00, 00, 00, 00, }, {65, 73, 00, 00, 00, 00, }, - {65, 78, 00, 00, 00, 00, }, {65, 78, 71, 00, 00, 00, }, - {65, 79, 00, 00, 00, 00, }, {66, 65, 00, 00, 00, 00, }, - {66, 65, 73, 00, 00, 00, }, {66, 65, 78, 00, 00, 00, }, - {66, 65, 78, 71, 00, 00, }, {66, 65, 79, 00, 00, 00, }, - {66, 69, 73, 00, 00, 00, }, {66, 69, 78, 00, 00, 00, }, - {66, 69, 78, 71, 00, 00, }, {66, 73, 00, 00, 00, 00, }, - {66, 73, 65, 78, 00, 00, }, {66, 73, 65, 79, 00, 00, }, - {66, 73, 69, 00, 00, 00, }, {66, 73, 78, 00, 00, 00, }, - {66, 73, 78, 71, 00, 00, }, {66, 79, 00, 00, 00, 00, }, - {66, 85, 00, 00, 00, 00, }, {67, 65, 00, 00, 00, 00, }, - {67, 65, 73, 00, 00, 00, }, {67, 65, 78, 00, 00, 00, }, - {67, 65, 78, 71, 00, 00, }, {67, 65, 79, 00, 00, 00, }, - {67, 69, 00, 00, 00, 00, }, {67, 69, 78, 00, 00, 00, }, - {67, 69, 78, 71, 00, 00, }, {67, 72, 65, 00, 00, 00, }, - {67, 72, 65, 73, 00, 00, }, {67, 72, 65, 78, 00, 00, }, - {67, 72, 65, 78, 71, 00, }, {67, 72, 65, 79, 00, 00, }, - {67, 72, 69, 00, 00, 00, }, {67, 72, 69, 78, 00, 00, }, - {67, 72, 69, 78, 71, 00, }, {67, 72, 73, 00, 00, 00, }, - {67, 72, 79, 78, 71, 00, }, {67, 72, 79, 85, 00, 00, }, - {67, 72, 85, 00, 00, 00, }, {67, 72, 85, 65, 73, 00, }, - {67, 72, 85, 65, 78, 00, }, {67, 72, 85, 65, 78, 71, }, - {67, 72, 85, 73, 00, 00, }, {67, 72, 85, 78, 00, 00, }, - {67, 72, 85, 79, 00, 00, }, {67, 73, 00, 00, 00, 00, }, - {67, 79, 78, 71, 00, 00, }, {67, 79, 85, 00, 00, 00, }, - {67, 85, 00, 00, 00, 00, }, {67, 85, 65, 78, 00, 00, }, - {67, 85, 73, 00, 00, 00, }, {67, 85, 78, 00, 00, 00, }, - {67, 85, 79, 00, 00, 00, }, {68, 65, 00, 00, 00, 00, }, - {68, 65, 73, 00, 00, 00, }, {68, 65, 78, 00, 00, 00, }, - {68, 65, 78, 71, 00, 00, }, {68, 65, 79, 00, 00, 00, }, - {68, 69, 00, 00, 00, 00, }, {68, 69, 78, 00, 00, 00, }, - {68, 69, 78, 71, 00, 00, }, {68, 73, 00, 00, 00, 00, }, - {68, 73, 65, 00, 00, 00, }, {68, 73, 65, 78, 00, 00, }, - {68, 73, 65, 79, 00, 00, }, {68, 73, 69, 00, 00, 00, }, - {68, 73, 78, 71, 00, 00, }, {68, 73, 85, 00, 00, 00, }, - {68, 79, 78, 71, 00, 00, }, {68, 79, 85, 00, 00, 00, }, - {68, 85, 00, 00, 00, 00, }, {68, 85, 65, 78, 00, 00, }, - {68, 85, 73, 00, 00, 00, }, {68, 85, 78, 00, 00, 00, }, - {68, 85, 79, 00, 00, 00, }, {69, 00, 00, 00, 00, 00, }, - {69, 78, 00, 00, 00, 00, }, {69, 78, 71, 00, 00, 00, }, - {69, 82, 00, 00, 00, 00, }, {70, 65, 00, 00, 00, 00, }, - {70, 65, 78, 00, 00, 00, }, {70, 65, 78, 71, 00, 00, }, - {70, 69, 73, 00, 00, 00, }, {70, 69, 78, 00, 00, 00, }, - {70, 69, 78, 71, 00, 00, }, {70, 73, 65, 79, 00, 00, }, - {70, 79, 00, 00, 00, 00, }, {70, 85, 00, 00, 00, 00, }, - {70, 79, 85, 00, 00, 00, }, {70, 85, 00, 00, 00, 00, }, - {71, 85, 73, 00, 00, 00, }, {71, 65, 00, 00, 00, 00, }, - {71, 65, 73, 00, 00, 00, }, {71, 65, 78, 00, 00, 00, }, - {71, 65, 78, 71, 00, 00, }, {71, 65, 79, 00, 00, 00, }, - {71, 69, 00, 00, 00, 00, }, {71, 69, 73, 00, 00, 00, }, - {71, 69, 78, 00, 00, 00, }, {71, 69, 78, 71, 00, 00, }, - {74, 73, 69, 00, 00, 00, }, {71, 69, 00, 00, 00, 00, }, - {71, 79, 78, 71, 00, 00, }, {71, 79, 85, 00, 00, 00, }, - {71, 85, 00, 00, 00, 00, }, {71, 85, 65, 00, 00, 00, }, - {71, 85, 65, 73, 00, 00, }, {71, 85, 65, 78, 00, 00, }, - {71, 85, 65, 78, 71, 00, }, {71, 85, 73, 00, 00, 00, }, - {71, 85, 78, 00, 00, 00, }, {71, 85, 65, 78, 00, 00, }, - {71, 85, 79, 00, 00, 00, }, {72, 65, 00, 00, 00, 00, }, - {72, 65, 73, 00, 00, 00, }, {72, 65, 78, 00, 00, 00, }, - {72, 65, 78, 71, 00, 00, }, {72, 65, 79, 00, 00, 00, }, - {72, 69, 00, 00, 00, 00, }, {72, 69, 73, 00, 00, 00, }, - {72, 69, 78, 00, 00, 00, }, {72, 69, 78, 71, 00, 00, }, - {72, 79, 78, 71, 00, 00, }, {72, 79, 85, 00, 00, 00, }, - {72, 85, 00, 00, 00, 00, }, {72, 85, 65, 00, 00, 00, }, - {72, 85, 65, 73, 00, 00, }, {72, 85, 65, 78, 00, 00, }, - {72, 85, 65, 78, 71, 00, }, {72, 85, 73, 00, 00, 00, }, - {72, 85, 78, 00, 00, 00, }, {72, 85, 79, 00, 00, 00, }, - {74, 73, 00, 00, 00, 00, }, {74, 73, 65, 00, 00, 00, }, - {74, 73, 65, 78, 00, 00, }, {74, 73, 65, 78, 71, 00, }, - {74, 73, 65, 79, 00, 00, }, {74, 73, 69, 00, 00, 00, }, - {74, 73, 78, 00, 00, 00, }, {74, 73, 78, 71, 00, 00, }, - {74, 73, 79, 78, 71, 00, }, {74, 73, 85, 00, 00, 00, }, - {74, 85, 00, 00, 00, 00, }, {74, 85, 65, 78, 00, 00, }, - {74, 85, 69, 00, 00, 00, }, {74, 85, 78, 00, 00, 00, }, - {75, 65, 00, 00, 00, 00, }, {75, 65, 73, 00, 00, 00, }, - {75, 65, 78, 00, 00, 00, }, {75, 65, 78, 71, 00, 00, }, - {75, 65, 79, 00, 00, 00, }, {75, 69, 00, 00, 00, 00, }, - {75, 69, 78, 00, 00, 00, }, {75, 69, 78, 71, 00, 00, }, - {75, 79, 78, 71, 00, 00, }, {75, 79, 85, 00, 00, 00, }, - {75, 85, 00, 00, 00, 00, }, {75, 85, 65, 00, 00, 00, }, - {75, 85, 65, 73, 00, 00, }, {75, 85, 65, 78, 00, 00, }, - {75, 85, 65, 78, 71, 00, }, {75, 85, 73, 00, 00, 00, }, - {75, 85, 78, 00, 00, 00, }, {75, 85, 79, 00, 00, 00, }, - {76, 65, 00, 00, 00, 00, }, {76, 65, 73, 00, 00, 00, }, - {76, 65, 78, 00, 00, 00, }, {76, 65, 78, 71, 00, 00, }, - {76, 65, 79, 00, 00, 00, }, {76, 69, 00, 00, 00, 00, }, - {76, 69, 73, 00, 00, 00, }, {76, 73, 00, 00, 00, 00, }, - {76, 73, 78, 71, 00, 00, }, {76, 69, 78, 71, 00, 00, }, - {76, 73, 00, 00, 00, 00, }, {76, 73, 65, 00, 00, 00, }, - {76, 73, 65, 78, 00, 00, }, {76, 73, 65, 78, 71, 00, }, - {76, 73, 65, 79, 00, 00, }, {76, 73, 69, 00, 00, 00, }, - {76, 73, 78, 00, 00, 00, }, {76, 73, 78, 71, 00, 00, }, - {76, 73, 85, 00, 00, 00, }, {76, 79, 78, 71, 00, 00, }, - {76, 79, 85, 00, 00, 00, }, {76, 85, 00, 00, 00, 00, }, - {76, 85, 65, 78, 00, 00, }, {76, 85, 78, 00, 00, 00, }, - {76, 85, 79, 00, 00, 00, }, {77, 65, 00, 00, 00, 00, }, - {77, 65, 73, 00, 00, 00, }, {77, 65, 78, 00, 00, 00, }, - {77, 65, 78, 71, 00, 00, }, {77, 65, 79, 00, 00, 00, }, - {77, 69, 73, 00, 00, 00, }, {77, 69, 78, 00, 00, 00, }, - {77, 69, 78, 71, 00, 00, }, {77, 73, 00, 00, 00, 00, }, - {77, 73, 65, 78, 00, 00, }, {77, 73, 65, 79, 00, 00, }, - {77, 73, 69, 00, 00, 00, }, {77, 73, 78, 00, 00, 00, }, - {77, 73, 78, 71, 00, 00, }, {77, 73, 85, 00, 00, 00, }, - {77, 79, 00, 00, 00, 00, }, {77, 79, 85, 00, 00, 00, }, - {77, 85, 00, 00, 00, 00, }, {78, 65, 00, 00, 00, 00, }, - {78, 65, 73, 00, 00, 00, }, {78, 65, 78, 00, 00, 00, }, - {78, 65, 78, 71, 00, 00, }, {78, 65, 79, 00, 00, 00, }, - {78, 69, 00, 00, 00, 00, }, {78, 69, 73, 00, 00, 00, }, - {78, 69, 78, 00, 00, 00, }, {78, 69, 78, 71, 00, 00, }, - {78, 73, 00, 00, 00, 00, }, {78, 73, 65, 78, 00, 00, }, - {78, 73, 65, 78, 71, 00, }, {78, 73, 65, 79, 00, 00, }, - {78, 73, 69, 00, 00, 00, }, {78, 73, 78, 00, 00, 00, }, - {78, 73, 78, 71, 00, 00, }, {78, 73, 85, 00, 00, 00, }, - {78, 79, 78, 71, 00, 00, }, {78, 79, 85, 00, 00, 00, }, - {78, 85, 00, 00, 00, 00, }, {78, 85, 65, 78, 00, 00, }, - {78, 85, 78, 00, 00, 00, }, {78, 85, 79, 00, 00, 00, }, - {79, 00, 00, 00, 00, 00, }, {79, 85, 00, 00, 00, 00, }, - {80, 65, 00, 00, 00, 00, }, {80, 65, 73, 00, 00, 00, }, - {80, 65, 78, 00, 00, 00, }, {80, 65, 78, 71, 00, 00, }, - {80, 65, 79, 00, 00, 00, }, {80, 69, 73, 00, 00, 00, }, - {80, 69, 78, 00, 00, 00, }, {80, 69, 78, 71, 00, 00, }, - {80, 73, 00, 00, 00, 00, }, {80, 73, 65, 78, 00, 00, }, - {80, 73, 65, 79, 00, 00, }, {80, 73, 69, 00, 00, 00, }, - {80, 73, 78, 00, 00, 00, }, {80, 73, 78, 71, 00, 00, }, - {80, 79, 00, 00, 00, 00, }, {80, 79, 85, 00, 00, 00, }, - {80, 85, 00, 00, 00, 00, }, {81, 73, 00, 00, 00, 00, }, - {81, 73, 65, 00, 00, 00, }, {81, 73, 65, 78, 00, 00, }, - {81, 73, 65, 78, 71, 00, }, {81, 73, 65, 79, 00, 00, }, - {81, 73, 69, 00, 00, 00, }, {81, 73, 78, 00, 00, 00, }, - {81, 73, 78, 71, 00, 00, }, {81, 73, 79, 78, 71, 00, }, - {81, 73, 85, 00, 00, 00, }, {81, 85, 00, 00, 00, 00, }, - {81, 85, 65, 78, 00, 00, }, {81, 85, 69, 00, 00, 00, }, - {81, 85, 78, 00, 00, 00, }, {82, 65, 78, 00, 00, 00, }, - {82, 65, 78, 71, 00, 00, }, {82, 65, 79, 00, 00, 00, }, - {82, 69, 00, 00, 00, 00, }, {82, 69, 78, 00, 00, 00, }, - {82, 69, 78, 71, 00, 00, }, {82, 73, 00, 00, 00, 00, }, - {82, 79, 78, 71, 00, 00, }, {82, 79, 85, 00, 00, 00, }, - {82, 85, 00, 00, 00, 00, }, {82, 85, 65, 78, 00, 00, }, - {82, 85, 73, 00, 00, 00, }, {82, 85, 78, 00, 00, 00, }, - {82, 85, 79, 00, 00, 00, }, {83, 65, 00, 00, 00, 00, }, - {83, 65, 73, 00, 00, 00, }, {83, 65, 78, 00, 00, 00, }, - {83, 65, 78, 71, 00, 00, }, {83, 65, 79, 00, 00, 00, }, - {83, 69, 00, 00, 00, 00, }, {83, 69, 78, 00, 00, 00, }, - {83, 69, 78, 71, 00, 00, }, {83, 72, 65, 00, 00, 00, }, - {83, 72, 65, 73, 00, 00, }, {83, 72, 65, 78, 00, 00, }, - {83, 72, 65, 78, 71, 00, }, {83, 72, 65, 79, 00, 00, }, - {83, 72, 69, 00, 00, 00, }, {83, 72, 69, 78, 00, 00, }, - {83, 72, 69, 78, 71, 00, }, {83, 72, 73, 00, 00, 00, }, - {83, 72, 79, 85, 00, 00, }, {83, 72, 85, 00, 00, 00, }, - {83, 72, 85, 65, 00, 00, }, {83, 72, 85, 65, 73, 00, }, - {83, 72, 85, 65, 78, 00, }, {83, 72, 85, 65, 78, 71, }, - {83, 72, 85, 73, 00, 00, }, {83, 72, 85, 78, 00, 00, }, - {83, 72, 85, 79, 00, 00, }, {83, 73, 00, 00, 00, 00, }, - {83, 79, 78, 71, 00, 00, }, {83, 79, 85, 00, 00, 00, }, - {83, 85, 00, 00, 00, 00, }, {83, 85, 65, 78, 00, 00, }, - {83, 85, 73, 00, 00, 00, }, {83, 85, 78, 00, 00, 00, }, - {83, 85, 79, 00, 00, 00, }, {84, 65, 00, 00, 00, 00, }, - {84, 65, 73, 00, 00, 00, }, {84, 65, 78, 00, 00, 00, }, - {84, 65, 78, 71, 00, 00, }, {84, 65, 79, 00, 00, 00, }, - {84, 69, 00, 00, 00, 00, }, {84, 69, 78, 71, 00, 00, }, - {84, 73, 00, 00, 00, 00, }, {84, 73, 65, 78, 00, 00, }, - {84, 73, 65, 79, 00, 00, }, {84, 73, 69, 00, 00, 00, }, - {84, 73, 78, 71, 00, 00, }, {84, 79, 78, 71, 00, 00, }, - {84, 79, 85, 00, 00, 00, }, {84, 85, 00, 00, 00, 00, }, - {84, 85, 65, 78, 00, 00, }, {84, 85, 73, 00, 00, 00, }, - {84, 85, 78, 00, 00, 00, }, {84, 85, 79, 00, 00, 00, }, - {87, 65, 00, 00, 00, 00, }, {87, 65, 73, 00, 00, 00, }, - {87, 65, 78, 00, 00, 00, }, {87, 65, 78, 71, 00, 00, }, - {87, 69, 73, 00, 00, 00, }, {87, 69, 78, 00, 00, 00, }, - {87, 69, 78, 71, 00, 00, }, {87, 79, 00, 00, 00, 00, }, - {87, 85, 00, 00, 00, 00, }, {88, 73, 00, 00, 00, 00, }, - {88, 73, 65, 00, 00, 00, }, {88, 73, 65, 78, 00, 00, }, - {88, 73, 65, 78, 71, 00, }, {88, 73, 65, 79, 00, 00, }, - {88, 73, 69, 00, 00, 00, }, {88, 73, 78, 00, 00, 00, }, - {88, 73, 78, 71, 00, 00, }, {88, 73, 79, 78, 71, 00, }, - {88, 73, 85, 00, 00, 00, }, {88, 85, 00, 00, 00, 00, }, - {88, 85, 65, 78, 00, 00, }, {88, 85, 69, 00, 00, 00, }, - {88, 85, 78, 00, 00, 00, }, {89, 65, 00, 00, 00, 00, }, - {89, 65, 78, 00, 00, 00, }, {89, 65, 78, 71, 00, 00, }, - {89, 65, 79, 00, 00, 00, }, {89, 69, 00, 00, 00, 00, }, - {89, 73, 00, 00, 00, 00, }, {89, 73, 78, 00, 00, 00, }, - {89, 73, 78, 71, 00, 00, }, {89, 79, 00, 00, 00, 00, }, - {89, 79, 78, 71, 00, 00, }, {89, 79, 85, 00, 00, 00, }, - {89, 85, 00, 00, 00, 00, }, {89, 85, 65, 78, 00, 00, }, - {89, 85, 69, 00, 00, 00, }, {89, 85, 78, 00, 00, 00, }, - {90, 65, 00, 00, 00, 00, }, {90, 65, 73, 00, 00, 00, }, - {90, 65, 78, 00, 00, 00, }, {90, 65, 78, 71, 00, 00, }, - {90, 65, 79, 00, 00, 00, }, {90, 69, 00, 00, 00, 00, }, - {90, 69, 73, 00, 00, 00, }, {90, 69, 78, 00, 00, 00, }, - {90, 69, 78, 71, 00, 00, }, {90, 72, 65, 00, 00, 00, }, - {90, 72, 65, 73, 00, 00, }, {90, 72, 65, 78, 00, 00, }, - {90, 72, 65, 78, 71, 00, }, {90, 72, 65, 79, 00, 00, }, - {90, 72, 69, 00, 00, 00, }, {90, 72, 69, 78, 00, 00, }, - {90, 72, 69, 78, 71, 00, }, {90, 72, 73, 00, 00, 00, }, - {90, 72, 79, 78, 71, 00, }, {90, 72, 79, 85, 00, 00, }, - {90, 72, 85, 00, 00, 00, }, {90, 72, 85, 65, 00, 00, }, - {90, 72, 85, 65, 73, 00, }, {90, 72, 85, 65, 78, 00, }, - {90, 72, 85, 65, 78, 71, }, {90, 72, 85, 73, 00, 00, }, - {90, 72, 85, 78, 00, 00, }, {90, 72, 85, 79, 00, 00, }, - {90, 73, 00, 00, 00, 00, }, {90, 79, 78, 71, 00, 00, }, - {90, 79, 85, 00, 00, 00, }, {90, 85, 00, 00, 00, 00, }, - {90, 85, 65, 78, 00, 00, }, {90, 85, 73, 00, 00, 00, }, - {90, 85, 78, 00, 00, 00, }, {90, 85, 79, 00, 00, 00, }, - - }; - - /** First and last Chinese character with known Pinyin according to zh collation */ - private static final String FIRST_PINYIN_UNIHAN = "\u5416"; - private static final String LAST_PINYIN_UNIHAN = "\u5497"; - /** The first Chinese character in Unicode block */ - private static final char FIRST_UNIHAN = '\u3400'; - private static final Collator COLLATOR = Collator.getInstance(Locale.CHINA); - - private static HanziToPinyin sInstance; - private final boolean mHasChinaCollator; - - public static class Token { - /** - * Separator between target string for each source char - */ - public static final String SEPARATOR = " "; - - public static final int LATIN = 1; - public static final int PINYIN = 2; - public static final int UNKNOWN = 3; - - public Token() { - } - - public Token(int type, String source, String target) { - this.type = type; - this.source = source; - this.target = target; - } - /** - * Type of this token, ASCII, PINYIN or UNKNOWN. - */ - public int type; - /** - * Original string before translation. - */ - public String source; - /** - * Translated string of source. For Han, target is corresponding Pinyin. - * Otherwise target is original string in source. - */ - public String target; - } - - protected HanziToPinyin(boolean hasChinaCollator) { - mHasChinaCollator = hasChinaCollator; - } - - public static HanziToPinyin getInstance() { - synchronized(HanziToPinyin.class) { - if (sInstance != null) { - return sInstance; - } - // Check if zh_CN collation data is available - final Locale locale[] = Collator.getAvailableLocales(); - for (int i = 0; i < locale.length; i++) { - if (locale[i].equals(Locale.CHINA)) { - sInstance = new HanziToPinyin(true); - return sInstance; - } - } - Log.w(TAG, "There is no Chinese collator, HanziToPinyin is disabled"); - sInstance = new HanziToPinyin(false); - return sInstance; - } - } - - private Token getToken(char character) { - Token token = new Token(); - final String letter = Character.toString(character); - token.source = letter; - int offset = -1; - int cmp; - if (character < 256) { - token.type = Token.LATIN; - token.target = letter; - return token; - } else if (character < FIRST_UNIHAN) { - token.type = Token.UNKNOWN; - token.target = letter; - return token; - } else { - cmp = COLLATOR.compare(letter, FIRST_PINYIN_UNIHAN); - if (cmp < 0) { - token.type = Token.UNKNOWN; - token.target = letter; - return token; - } else if (cmp == 0) { - token.type = Token.PINYIN; - offset = 0; - } else { - cmp = COLLATOR.compare(letter, LAST_PINYIN_UNIHAN); - if (cmp > 0) { - token.type = Token.UNKNOWN; - token.target = letter; - return token; - } else if (cmp == 0) { - token.type = Token.PINYIN; - offset = UNIHANS.length - 1; - } - } - } - - token.type = Token.PINYIN; - if (offset < 0) { - int begin = 0; - int end = UNIHANS.length - 1; - while (begin <= end) { - offset = (begin + end) / 2; - final String unihan = Character.toString(UNIHANS[offset]); - cmp = COLLATOR.compare(letter, unihan); - if (cmp == 0) { - break; - } else if (cmp > 0) { - begin = offset + 1; - } else { - end = offset - 1; - } - } - } - if (cmp < 0) { - offset--; - } - StringBuilder pinyin = new StringBuilder(); - for (int j = 0; j < PINYINS[offset].length && PINYINS[offset][j] != 0; j++) { - pinyin.append((char)PINYINS[offset][j]); - } - token.target = pinyin.toString(); - return token; - } - - /** - * Convert the input to a array of tokens. The sequence of ASCII or Unknown - * characters without space will be put into a Token, One Hanzi character - * which has pinyin will be treated as a Token. - * If these is no China collator, the empty token array is returned. - */ - public ArrayList<Token> get(final String input) { - ArrayList<Token> tokens = new ArrayList<Token>(); - if (!mHasChinaCollator || TextUtils.isEmpty(input)) { - // return empty tokens. - return tokens; - } - final int inputLength = input.length(); - final StringBuilder sb = new StringBuilder(); - int tokenType = Token.LATIN; - // Go through the input, create a new token when - // a. Token type changed - // b. Get the Pinyin of current charater. - // c. current character is space. - for (int i = 0; i < inputLength; i++) { - final char character = input.charAt(i); - if (character == ' ') { - if (sb.length() > 0) { - addToken(sb, tokens, tokenType); - } - } else if (character < 256) { - if (tokenType != Token.LATIN && sb.length() > 0) { - addToken(sb, tokens, tokenType); - } - tokenType = Token.LATIN; - sb.append(character); - } else if (character < FIRST_UNIHAN) { - if (tokenType != Token.UNKNOWN && sb.length() > 0) { - addToken(sb, tokens, tokenType); - } - tokenType = Token.UNKNOWN; - sb.append(character); - } else { - Token t = getToken(character); - if (t.type == Token.PINYIN) { - if (sb.length() > 0) { - addToken(sb, tokens, tokenType); - } - tokens.add(t); - tokenType = Token.PINYIN; - } else { - if (tokenType != t.type && sb.length() > 0) { - addToken(sb, tokens, tokenType); - } - tokenType = t.type; - sb.append(character); - } - } - } - if (sb.length() > 0) { - addToken(sb, tokens, tokenType); - } - return tokens; - } - - private void addToken(final StringBuilder sb, final ArrayList<Token> tokens, - final int tokenType) { - String str = sb.toString(); - tokens.add(new Token(tokenType, str, str)); - sb.setLength(0); - } - -} diff --git a/core/java/com/android/internal/view/menu/ListMenuPresenter.java b/core/java/com/android/internal/view/menu/ListMenuPresenter.java index f8d24a3..cc09927 100644 --- a/core/java/com/android/internal/view/menu/ListMenuPresenter.java +++ b/core/java/com/android/internal/view/menu/ListMenuPresenter.java @@ -177,7 +177,9 @@ public class ListMenuPresenter implements MenuPresenter, AdapterView.OnItemClick public void restoreHierarchyState(Bundle inState) { SparseArray<Parcelable> viewStates = inState.getSparseParcelableArray(VIEWS_TAG); - ((View) mMenuView).restoreHierarchyState(viewStates); + if (viewStates != null) { + ((View) mMenuView).restoreHierarchyState(viewStates); + } } private class MenuAdapter extends BaseAdapter { diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java index 5767519..8db7e3c 100644 --- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java +++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java @@ -17,6 +17,7 @@ package com.android.internal.view.menu; import android.content.Context; +import android.content.res.Resources; import android.util.DisplayMetrics; import android.view.KeyEvent; import android.view.LayoutInflater; @@ -71,8 +72,9 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On mMenu = menu; mOverflowOnly = overflowOnly; - final DisplayMetrics metrics = context.getResources().getDisplayMetrics(); - mPopupMaxWidth = metrics.widthPixels / 2; + final Resources res = context.getResources(); + mPopupMaxWidth = Math.max(res.getDisplayMetrics().widthPixels / 2, + res.getDimensionPixelSize(com.android.internal.R.dimen.config_prefDialogWidth)); mAnchorView = anchorView; diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index a8aff37..47902a8 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -91,6 +91,8 @@ <protected-broadcast android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> <protected-broadcast android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" /> + <protected-broadcast android:name="android.net.vpn.action.REVOKED" /> + <protected-broadcast android:name="android.nfc.action.LLCP_LINK_STATE_CHANGED" /> <protected-broadcast android:name="com.android.nfc_extras.action.RF_FIELD_ON_DETECTED" /> <protected-broadcast android:name="com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED" /> diff --git a/core/res/res/layout/select_dialog_item_holo.xml b/core/res/res/layout/select_dialog_item_holo.xml index 396092e..0c700cf 100644 --- a/core/res/res/layout/select_dialog_item_holo.xml +++ b/core/res/res/layout/select_dialog_item_holo.xml @@ -26,7 +26,7 @@ android:id="@android:id/text1" android:layout_width="match_parent" android:layout_height="wrap_content" - android:minHeight="?android:attr/listPreferredItemHeight" + android:minHeight="?android:attr/listPreferredItemHeightSmall" android:textAppearance="?android:attr/textAppearanceMedium" android:textColor="?android:attr/textColorAlertDialogListItem" android:gravity="center_vertical" diff --git a/core/res/res/layout/select_dialog_multichoice_holo.xml b/core/res/res/layout/select_dialog_multichoice_holo.xml index 8027035..683151c 100644 --- a/core/res/res/layout/select_dialog_multichoice_holo.xml +++ b/core/res/res/layout/select_dialog_multichoice_holo.xml @@ -18,7 +18,7 @@ android:id="@android:id/text1" android:layout_width="match_parent" android:layout_height="wrap_content" - android:minHeight="?android:attr/listPreferredItemHeight" + android:minHeight="?android:attr/listPreferredItemHeightSmall" android:textAppearance="?android:attr/textAppearanceMedium" android:textColor="?android:attr/textColorAlertDialogListItem" android:gravity="center_vertical" diff --git a/core/res/res/layout/select_dialog_singlechoice_holo.xml b/core/res/res/layout/select_dialog_singlechoice_holo.xml index cab519f..52782d0 100644 --- a/core/res/res/layout/select_dialog_singlechoice_holo.xml +++ b/core/res/res/layout/select_dialog_singlechoice_holo.xml @@ -18,7 +18,7 @@ android:id="@android:id/text1" android:layout_width="match_parent" android:layout_height="wrap_content" - android:minHeight="?android:attr/listPreferredItemHeight" + android:minHeight="?android:attr/listPreferredItemHeightSmall" android:textAppearance="?android:attr/textAppearanceMedium" android:textColor="?android:attr/textColorAlertDialogListItem" android:gravity="center_vertical" diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index df4322c..a59af1a 100755 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -202,9 +202,14 @@ <!-- The preferred list item height. --> <attr name="listPreferredItemHeight" format="dimension" /> - <!-- The drawable for the list divider. --> + <!-- A smaller, sleeker list item height. --> + <attr name="listPreferredItemHeightSmall" format="dimension" /> + <!-- A larger, more robust list item height. --> + <attr name="listPreferredItemHeightLarge" format="dimension" /> <!-- The list item height for search results. @hide --> <attr name="searchResultListItemHeight" format="dimension" /> + + <!-- The drawable for the list divider. --> <attr name="listDivider" format="reference" /> <!-- The list divider used in alert dialogs. --> <attr name="listDividerAlertDialog" format="reference" /> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 807d73c..e02496c 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -1766,6 +1766,8 @@ <public type="attr" name="feedbackCount" /> <public type="attr" name="verticalOffset" /> <public type="attr" name="horizontalOffset" /> + <public type="attr" name="listPreferredItemHeightLarge" /> + <public type="attr" name="listPreferredItemHeightSmall" /> <public type="style" name="Widget.Holo.Button.Borderless.Small" /> <public type="style" name="Widget.Holo.Light.Button.Borderless.Small" /> diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml index 354414a..72a5797 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -1496,6 +1496,7 @@ <style name="Holo.ButtonBar.AlertDialog"> <item name="android:background">@null</item> + <item name="android:dividerPadding">0dp</item> </style> <style name="Widget.Holo.TextView" parent="Widget.TextView"> @@ -1905,6 +1906,7 @@ <style name="Holo.Light.ButtonBar.AlertDialog"> <item name="android:background">@null</item> + <item name="android:dividerPadding">0dp</item> </style> <style name="Holo.Light.SegmentedButton" parent="SegmentedButton"> diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml index 4a43e32..2ab2c04 100644 --- a/core/res/res/values/themes.xml +++ b/core/res/res/values/themes.xml @@ -95,7 +95,9 @@ <!-- List attributes --> <item name="listPreferredItemHeight">64dip</item> - <item name="dropdownListPreferredItemHeight">64dip</item> + <item name="listPreferredItemHeightSmall">?android:attr/listPreferredItemHeight</item> + <item name="listPreferredItemHeightLarge">?android:attr/listPreferredItemHeight</item> + <item name="dropdownListPreferredItemHeight">?android:attr/listPreferredItemHeight</item> <!-- @hide --> <item name="searchResultListItemHeight">58dip</item> @@ -861,7 +863,9 @@ <!-- List attributes --> <item name="listPreferredItemHeight">64dip</item> - <item name="dropdownListPreferredItemHeight">48dip</item> + <item name="listPreferredItemHeightSmall">48dip</item> + <item name="listPreferredItemHeightLarge">80dip</item> + <item name="dropdownListPreferredItemHeight">?android:attr/listPreferredItemHeightSmall</item> <!-- @hide --> <item name="searchResultListItemHeight">58dip</item> @@ -1150,7 +1154,9 @@ <!-- List attributes --> <item name="listPreferredItemHeight">64dip</item> - <item name="dropdownListPreferredItemHeight">48dip</item> + <item name="listPreferredItemHeightSmall">48dip</item> + <item name="listPreferredItemHeightLarge">80dip</item> + <item name="dropdownListPreferredItemHeight">?android:attr/listPreferredItemHeightSmall</item> <!-- @hide --> <item name="searchResultListItemHeight">58dip</item> diff --git a/core/tests/coretests/src/com/android/internal/util/HanziToPinyinTest.java b/core/tests/coretests/src/com/android/internal/util/HanziToPinyinTest.java deleted file mode 100644 index 36dee70..0000000 --- a/core/tests/coretests/src/com/android/internal/util/HanziToPinyinTest.java +++ /dev/null @@ -1,74 +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.internal.util; - -import java.text.Collator; -import java.util.Arrays; -import java.util.ArrayList; -import java.util.Locale; - -import android.test.suitebuilder.annotation.SmallTest; -import android.util.Log; - -import com.android.internal.util.HanziToPinyin; -import com.android.internal.util.HanziToPinyin.Token; - -import junit.framework.TestCase; - -public class HanziToPinyinTest extends TestCase { - private final static String ONE_HANZI = "\u675C"; - private final static String TWO_HANZI = "\u675C\u9D51"; - private final static String ASSIC = "test"; - private final static String ONE_UNKNOWN = "\uFF71"; - private final static String MISC = "test\u675C Test with space\uFF71\uFF71\u675C"; - - @SmallTest - public void testGetToken() throws Exception { - if (!Arrays.asList(Collator.getAvailableLocales()).contains(Locale.CHINA)) { - return; - } - ArrayList<Token> tokens = HanziToPinyin.getInstance().get(ONE_HANZI); - assertEquals(tokens.size(), 1); - assertEquals(tokens.get(0).type, Token.PINYIN); - assertTrue(tokens.get(0).target.equalsIgnoreCase("DU")); - - tokens = HanziToPinyin.getInstance().get(TWO_HANZI); - assertEquals(tokens.size(), 2); - assertEquals(tokens.get(0).type, Token.PINYIN); - assertEquals(tokens.get(1).type, Token.PINYIN); - assertTrue(tokens.get(0).target.equalsIgnoreCase("DU")); - assertTrue(tokens.get(1).target.equalsIgnoreCase("JUAN")); - - tokens = HanziToPinyin.getInstance().get(ASSIC); - assertEquals(tokens.size(), 1); - assertEquals(tokens.get(0).type, Token.LATIN); - - tokens = HanziToPinyin.getInstance().get(ONE_UNKNOWN); - assertEquals(tokens.size(), 1); - assertEquals(tokens.get(0).type, Token.UNKNOWN); - - tokens = HanziToPinyin.getInstance().get(MISC); - assertEquals(tokens.size(), 7); - assertEquals(tokens.get(0).type, Token.LATIN); - assertEquals(tokens.get(1).type, Token.PINYIN); - assertEquals(tokens.get(2).type, Token.LATIN); - assertEquals(tokens.get(3).type, Token.LATIN); - assertEquals(tokens.get(4).type, Token.LATIN); - assertEquals(tokens.get(5).type, Token.UNKNOWN); - assertEquals(tokens.get(6).type, Token.PINYIN); - } -} diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java index a63abb9..eeab9b4 100644 --- a/graphics/java/android/renderscript/Allocation.java +++ b/graphics/java/android/renderscript/Allocation.java @@ -606,9 +606,9 @@ public class Allocation extends BaseObj { */ public void copy1DRangeFrom(int off, int count, Allocation data, int dataOff) { mRS.nAllocationData2D(getID(), off, 0, - 0, Type.CubemapFace.POSITVE_X.mID, + 0, Type.CubemapFace.POSITIVE_X.mID, count, 1, data.getID(), dataOff, 0, - 0, Type.CubemapFace.POSITVE_X.mID); + 0, Type.CubemapFace.POSITIVE_X.mID); } private void validate2DRange(int xoff, int yoff, int w, int h) { @@ -675,9 +675,9 @@ public class Allocation extends BaseObj { mRS.validate(); validate2DRange(xoff, yoff, w, h); mRS.nAllocationData2D(getID(), xoff, yoff, - 0, Type.CubemapFace.POSITVE_X.mID, + 0, Type.CubemapFace.POSITIVE_X.mID, w, h, data.getID(), dataXoff, dataYoff, - 0, Type.CubemapFace.POSITVE_X.mID); + 0, Type.CubemapFace.POSITIVE_X.mID); } /** @@ -1048,15 +1048,15 @@ public class Allocation extends BaseObj { Allocation cubemap = Allocation.createTyped(rs, t, mips, usage); AllocationAdapter adapter = AllocationAdapter.create2D(rs, cubemap); - adapter.setFace(Type.CubemapFace.POSITVE_X); + adapter.setFace(Type.CubemapFace.POSITIVE_X); adapter.copyFrom(xpos); adapter.setFace(Type.CubemapFace.NEGATIVE_X); adapter.copyFrom(xneg); - adapter.setFace(Type.CubemapFace.POSITVE_Y); + adapter.setFace(Type.CubemapFace.POSITIVE_Y); adapter.copyFrom(ypos); adapter.setFace(Type.CubemapFace.NEGATIVE_Y); adapter.copyFrom(yneg); - adapter.setFace(Type.CubemapFace.POSITVE_Z); + adapter.setFace(Type.CubemapFace.POSITIVE_Z); adapter.copyFrom(zpos); adapter.setFace(Type.CubemapFace.NEGATIVE_Z); adapter.copyFrom(zneg); diff --git a/graphics/java/android/renderscript/AllocationAdapter.java b/graphics/java/android/renderscript/AllocationAdapter.java index 07a1f5d..61f2e1f 100644 --- a/graphics/java/android/renderscript/AllocationAdapter.java +++ b/graphics/java/android/renderscript/AllocationAdapter.java @@ -33,7 +33,7 @@ public class AllocationAdapter extends Allocation { private Allocation mAlloc; private int mSelectedLOD = 0; - private Type.CubemapFace mSelectedFace = Type.CubemapFace.POSITVE_X; + private Type.CubemapFace mSelectedFace = Type.CubemapFace.POSITIVE_X; AllocationAdapter(int id, RenderScript rs, Allocation alloc) { super(id, rs, null, alloc.mUsage); diff --git a/graphics/java/android/renderscript/Element.java b/graphics/java/android/renderscript/Element.java index 0c1ad2a..5a72dbe 100644 --- a/graphics/java/android/renderscript/Element.java +++ b/graphics/java/android/renderscript/Element.java @@ -32,8 +32,8 @@ import android.util.Log; * <p>Complex elements contain a list of sub-elements and names that * represents a structure of data. The fields can be accessed by name * from a script or shader. The memory layout is defined and ordered. Data - * alignment is determinied by the most basic primitive type. i.e. a float4 - * vector will be alligned to sizeof(float) and not sizeof(float4). The + * alignment is determined by the most basic primitive type. i.e. a float4 + * vector will be aligned to sizeof(float) and not sizeof(float4). The * ordering of elements in memory will be the order in which they were added * with each component aligned as necessary. No re-ordering will be done.</p> * @@ -584,6 +584,33 @@ public class Element extends BaseObj { } /** + * Check if the current Element is compatible with another Element. + * Primitive Elements are compatible if they share the same underlying + * size and type (i.e. U8 is compatible with A_8). User-defined Elements + * must be equal in order to be compatible. This requires strict name + * equivalence for all sub-Elements (in addition to structural equivalence). + * + * @param e The Element to check compatibility with. + * + * @return boolean true if the Elements are compatible, otherwise false. + */ + public boolean isCompatible(Element e) { + // Try strict BaseObj equality to start with. + if (this.equals(e)) { + return true; + } + + // Ignore mKind because it is allowed to be different (user vs. pixel). + // We also ignore mNormalized because it can be different. The mType + // field must be non-null since we require name equivalence for + // user-created Elements. + return ((mSize == e.mSize) && + (mType != null) && + (mType == e.mType) && + (mVectorSize == e.mVectorSize)); + } + + /** * Builder class for producing complex elements with matching field and name * pairs. The builder starts empty. The order in which elements are added * is retained for the layout in memory. diff --git a/graphics/java/android/renderscript/Type.java b/graphics/java/android/renderscript/Type.java index b39d2e4..f88af8b 100644 --- a/graphics/java/android/renderscript/Type.java +++ b/graphics/java/android/renderscript/Type.java @@ -46,12 +46,18 @@ public class Type extends BaseObj { Element mElement; public enum CubemapFace { - POSITVE_X (0), + POSITIVE_X (0), NEGATIVE_X (1), - POSITVE_Y (2), + POSITIVE_Y (2), NEGATIVE_Y (3), - POSITVE_Z (4), - NEGATIVE_Z (5); + POSITIVE_Z (4), + NEGATIVE_Z (5), + @Deprecated + POSITVE_X (0), + @Deprecated + POSITVE_Y (2), + @Deprecated + POSITVE_Z (4); int mID; CubemapFace(int id) { diff --git a/libs/hwui/ShapeCache.h b/libs/hwui/ShapeCache.h index b5cc29c..b048469 100644 --- a/libs/hwui/ShapeCache.h +++ b/libs/hwui/ShapeCache.h @@ -537,15 +537,16 @@ PathTexture* ShapeCache<Entry>::addTexture(const Entry& entry, const SkPath *pat const float pathWidth = fmax(bounds.width(), 1.0f); const float pathHeight = fmax(bounds.height(), 1.0f); - if (pathWidth > mMaxTextureSize || pathHeight > mMaxTextureSize) { - LOGW("Shape %s too large to be rendered into a texture", mName); - return NULL; - } + const float offset = fmax(paint->getStrokeWidth(), 1.0f) * 1.5f; - const float offset = paint->getStrokeWidth() * 1.5f; const uint32_t width = uint32_t(pathWidth + offset * 2.0 + 0.5); const uint32_t height = uint32_t(pathHeight + offset * 2.0 + 0.5); + if (width > mMaxTextureSize || height > mMaxTextureSize) { + LOGW("Shape %s too large to be rendered into a texture", mName); + return NULL; + } + const uint32_t size = width * height; // Don't even try to cache a bitmap that's bigger than the cache if (size < mMaxSize) { diff --git a/media/libeffects/factory/EffectsFactory.c b/media/libeffects/factory/EffectsFactory.c index b0e8585..a3e76d9 100644 --- a/media/libeffects/factory/EffectsFactory.c +++ b/media/libeffects/factory/EffectsFactory.c @@ -257,7 +257,7 @@ int EffectCreate(effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, effect_ha } // create effect in library - l->desc->create_effect(uuid, sessionId, ioId, &itfe); + ret = l->desc->create_effect(uuid, sessionId, ioId, &itfe); if (ret != 0) { LOGW("EffectCreate() library %s: could not create fx %s, error %d", l->name, d->name, ret); goto exit; diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp index 28add18..58f03a0 100644 --- a/media/libstagefright/MPEG4Writer.cpp +++ b/media/libstagefright/MPEG4Writer.cpp @@ -1975,7 +1975,17 @@ status_t MPEG4Writer::Track::threadEntry() { int64_t previousPausedDurationUs = 0; int64_t timestampUs = 0; int64_t cttsDeltaTimeUs = 0; + bool hasBFrames = false; +#if 1 + // XXX: Samsung's video encoder's output buffer timestamp + // is not correct. see bug 4724339 + char value[PROPERTY_VALUE_MAX]; + if (property_get("rw.media.record.hasb", value, NULL) && + (!strcasecmp(value, "true") || !strcasecmp(value, "1"))) { + hasBFrames = true; + } +#endif if (mIsAudio) { prctl(PR_SET_NAME, (unsigned long)"AudioTrackEncoding", 0, 0, 0); } else { @@ -2118,7 +2128,7 @@ status_t MPEG4Writer::Track::threadEntry() { timestampUs -= previousPausedDurationUs; CHECK(timestampUs >= 0); - if (!mIsAudio) { + if (!mIsAudio && hasBFrames) { /* * Composition time: timestampUs * Decoding time: decodingTimeUs diff --git a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java index f1da49d..ba3f344 100644 --- a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java +++ b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java @@ -35,16 +35,16 @@ import android.widget.CompoundButton; import android.widget.ImageView; import android.widget.TextView; +import com.android.internal.net.VpnConfig; + import java.io.DataInputStream; import java.io.FileInputStream; -public class ManageDialog extends Activity implements +public class ManageDialog extends Activity implements Handler.Callback, DialogInterface.OnClickListener, DialogInterface.OnDismissListener { private static final String TAG = "VpnManage"; - private String mPackageName; - private String mInterfaceName; - private long mStartTime; + private VpnConfig mConfig; private IConnectivityManager mService; @@ -53,28 +53,23 @@ public class ManageDialog extends Activity implements private TextView mDataTransmitted; private TextView mDataReceived; - private Updater mUpdater; + private Handler mHandler; @Override protected void onResume() { super.onResume(); try { - Intent intent = getIntent(); - // TODO: Move constants into VpnBuilder. - mPackageName = intent.getStringExtra("packageName"); - mInterfaceName = intent.getStringExtra("interfaceName"); - mStartTime = intent.getLongExtra("startTime", 0); + mConfig = getIntent().getParcelableExtra("config"); mService = IConnectivityManager.Stub.asInterface( ServiceManager.getService(Context.CONNECTIVITY_SERVICE)); PackageManager pm = getPackageManager(); - ApplicationInfo app = pm.getApplicationInfo(mPackageName, 0); + ApplicationInfo app = pm.getApplicationInfo(mConfig.packageName, 0); View view = View.inflate(this, R.layout.manage, null); - String session = intent.getStringExtra("session"); - if (session != null) { - ((TextView) view.findViewById(R.id.session)).setText(session); + if (mConfig.sessionName != null) { + ((TextView) view.findViewById(R.id.session)).setText(mConfig.sessionName); } mDuration = (TextView) view.findViewById(R.id.duration); mDataTransmitted = (TextView) view.findViewById(R.id.data_transmitted); @@ -84,15 +79,21 @@ public class ManageDialog extends Activity implements .setIcon(app.loadIcon(pm)) .setTitle(app.loadLabel(pm)) .setView(view) - .setPositiveButton(R.string.configure, this) .setNeutralButton(R.string.disconnect, this) .setNegativeButton(android.R.string.cancel, this) .create(); + + if (mConfig.configureActivity != null) { + mDialog.setButton(DialogInterface.BUTTON_POSITIVE, + getText(R.string.configure), this); + } mDialog.setOnDismissListener(this); mDialog.show(); - mUpdater = new Updater(); - mUpdater.sendEmptyMessage(0); + if (mHandler == null) { + mHandler = new Handler(this); + } + mHandler.sendEmptyMessage(0); } catch (Exception e) { Log.e(TAG, "onResume", e); finish(); @@ -112,14 +113,15 @@ public class ManageDialog extends Activity implements public void onClick(DialogInterface dialog, int which) { try { if (which == AlertDialog.BUTTON_POSITIVE) { - Intent intent = new Intent(Intent.ACTION_MAIN); - intent.setPackage(mPackageName); + Intent intent = new Intent(); + intent.setClassName(mConfig.packageName, mConfig.configureActivity); startActivity(intent); } else if (which == AlertDialog.BUTTON_NEUTRAL) { - mService.prepareVpn(mPackageName); + mService.prepareVpn(""); } } catch (Exception e) { Log.e(TAG, "onClick", e); + finish(); } } @@ -128,30 +130,30 @@ public class ManageDialog extends Activity implements finish(); } - private class Updater extends Handler { - public void handleMessage(Message message) { - removeMessages(0); - - if (mDialog.isShowing()) { - if (mStartTime != 0) { - long seconds = (SystemClock.elapsedRealtime() - mStartTime) / 1000; - mDuration.setText(String.format("%02d:%02d:%02d", - seconds / 3600, seconds / 60 % 60, seconds % 60)); - } + @Override + public boolean handleMessage(Message message) { + mHandler.removeMessages(0); + + if (mDialog.isShowing()) { + if (mConfig.startTime != 0) { + long seconds = (SystemClock.elapsedRealtime() - mConfig.startTime) / 1000; + mDuration.setText(String.format("%02d:%02d:%02d", + seconds / 3600, seconds / 60 % 60, seconds % 60)); + } - String[] numbers = getStatistics(); - if (numbers != null) { - // [1] and [2] are received data in bytes and packets. - mDataReceived.setText(getString(R.string.data_value_format, - numbers[1], numbers[2])); + String[] numbers = getStatistics(); + if (numbers != null) { + // [1] and [2] are received data in bytes and packets. + mDataReceived.setText(getString(R.string.data_value_format, + numbers[1], numbers[2])); - // [9] and [10] are transmitted data in bytes and packets. - mDataTransmitted.setText(getString(R.string.data_value_format, - numbers[9], numbers[10])); - } - sendEmptyMessageDelayed(0, 1000); + // [9] and [10] are transmitted data in bytes and packets. + mDataTransmitted.setText(getString(R.string.data_value_format, + numbers[9], numbers[10])); } + mHandler.sendEmptyMessageDelayed(0, 1000); } + return true; } private String[] getStatistics() { @@ -159,7 +161,7 @@ public class ManageDialog extends Activity implements try { // See dev_seq_printf_stats() in net/core/dev.c. in = new DataInputStream(new FileInputStream("/proc/net/dev")); - String prefix = mInterfaceName + ':'; + String prefix = mConfig.interfaceName + ':'; while (true) { String line = in.readLine().trim(); diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index f1098a8..4ec71c1 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -1933,6 +1933,9 @@ public final class ActivityManagerService extends ActivityManagerNative int debugFlags = 0; if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; + // Also turn on CheckJNI for debuggable apps. It's quite + // awkward to turn on otherwise. + debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; } // Run the app in safe mode if its manifest requests so or the // system is booted in safe mode. diff --git a/services/java/com/android/server/connectivity/Vpn.java b/services/java/com/android/server/connectivity/Vpn.java index 372ba85..47813f8 100644 --- a/services/java/com/android/server/connectivity/Vpn.java +++ b/services/java/com/android/server/connectivity/Vpn.java @@ -18,7 +18,6 @@ package com.android.server.connectivity; import android.app.Notification; import android.app.NotificationManager; -import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; @@ -64,42 +63,61 @@ public class Vpn extends INetworkManagementEventObserver.Stub { * @return The name of the current prepared package. */ public synchronized String prepare(String packageName) { - - // TODO: Check if the caller is VpnDialogs. - + // Return the current prepared package if the new one is null. if (packageName == null) { return mPackageName; } - // Check the permission of the given application. + // Check the permission of the caller. PackageManager pm = mContext.getPackageManager(); - if (pm.checkPermission(VPN, packageName) != PackageManager.PERMISSION_GRANTED) { + VpnConfig.enforceCallingPackage(pm.getNameForUid(Binder.getCallingUid())); + + // Check the permission of the given package. + if (packageName.isEmpty()) { + packageName = null; + } else if (pm.checkPermission(VPN, packageName) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException(packageName + " does not have " + VPN); } // Reset the interface and hide the notification. if (mInterfaceName != null) { nativeReset(mInterfaceName); - mInterfaceName = null; + mCallback.restore(); hideNotification(); - // TODO: Send out a broadcast. + mInterfaceName = null; } + // Notify the package being revoked. + if (mPackageName != null) { + Intent intent = new Intent(VpnConfig.ACTION_VPN_REVOKED); + intent.setPackage(mPackageName); + intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); + mContext.sendBroadcast(intent); + } + + Log.i(TAG, "Switched from " + mPackageName + " to " + packageName); mPackageName = packageName; - Log.i(TAG, "Prepared for " + packageName); return mPackageName; } /** * Protect a socket from routing changes by binding it to the given - * interface. The socket is NOT closed by this method. + * interface. The socket IS closed by this method. * * @param socket The socket to be bound. * @param name The name of the interface. */ public void protect(ParcelFileDescriptor socket, String name) { - mContext.enforceCallingPermission(VPN, "protect"); - nativeProtect(socket.getFd(), name); + try { + mContext.enforceCallingPermission(VPN, "protect"); + nativeProtect(socket.getFd(), name); + } finally { + try { + socket.close(); + } catch (Exception e) { + // ignore + } + } } /** @@ -118,10 +136,10 @@ public class Vpn extends INetworkManagementEventObserver.Stub { try { app = pm.getApplicationInfo(mPackageName, 0); } catch (Exception e) { - throw new SecurityException("Not prepared"); + return null; } if (Binder.getCallingUid() != app.uid) { - throw new SecurityException("Not prepared"); + return null; } // Create and configure the interface. @@ -148,7 +166,9 @@ public class Vpn extends INetworkManagementEventObserver.Stub { String dnsServers = (config.dnsServers == null) ? "" : config.dnsServers.trim(); mCallback.override(dnsServers.isEmpty() ? null : dnsServers.split(" ")); - showNotification(pm, app, config.sessionName); + config.packageName = mPackageName; + config.interfaceName = mInterfaceName; + showNotification(pm, app, config); return descriptor; } @@ -169,7 +189,7 @@ public class Vpn extends INetworkManagementEventObserver.Stub { } } - private void showNotification(PackageManager pm, ApplicationInfo app, String sessionName) { + private void showNotification(PackageManager pm, ApplicationInfo app, VpnConfig config) { NotificationManager nm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); @@ -190,20 +210,9 @@ public class Vpn extends INetworkManagementEventObserver.Stub { // Load the label. String label = app.loadLabel(pm).toString(); - // Build the intent. - // TODO: move these into VpnBuilder. - Intent intent = new Intent(); - intent.setClassName("com.android.vpndialogs", - "com.android.vpndialogs.ManageDialog"); - intent.putExtra("packageName", mPackageName); - intent.putExtra("interfaceName", mInterfaceName); - intent.putExtra("session", sessionName); - intent.putExtra("startTime", android.os.SystemClock.elapsedRealtime()); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); - // Build the notification. - String text = (sessionName == null) ? mContext.getString(R.string.vpn_text) : - mContext.getString(R.string.vpn_text_long, sessionName); + String text = (config.sessionName == null) ? mContext.getString(R.string.vpn_text) : + mContext.getString(R.string.vpn_text_long, config.sessionName); long identity = Binder.clearCallingIdentity(); Notification notification = new Notification.Builder(mContext) .setSmallIcon(R.drawable.vpn_connected) @@ -211,7 +220,7 @@ public class Vpn extends INetworkManagementEventObserver.Stub { .setTicker(mContext.getString(R.string.vpn_ticker, label)) .setContentTitle(mContext.getString(R.string.vpn_title, label)) .setContentText(text) - .setContentIntent(PendingIntent.getActivity(mContext, 0, intent, 0)) + .setContentIntent(VpnConfig.getIntentForNotification(mContext, config)) .setDefaults(Notification.DEFAULT_ALL) .setOngoing(true) .getNotification(); diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java index e1fbe1c..5a9dae9 100644 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/java/com/android/server/pm/PackageManagerService.java @@ -18,6 +18,7 @@ package com.android.server.pm; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; +import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; import com.android.internal.app.IMediaContainerService; @@ -7048,7 +7049,8 @@ public class PackageManagerService extends IPackageManager.Stub { final String packageName, String className, int newState, final int flags) { if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT || newState == COMPONENT_ENABLED_STATE_ENABLED - || newState == COMPONENT_ENABLED_STATE_DISABLED)) { + || newState == COMPONENT_ENABLED_STATE_DISABLED + || newState == COMPONENT_ENABLED_STATE_DISABLED_USER)) { throw new IllegalArgumentException("Invalid new component state: " + newState); } diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java index 2720bf8..5ed7988 100644 --- a/services/java/com/android/server/pm/Settings.java +++ b/services/java/com/android/server/pm/Settings.java @@ -18,6 +18,7 @@ package com.android.server.pm; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; +import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; import com.android.internal.util.FastXmlSerializer; @@ -1912,6 +1913,7 @@ final class Settings { return false; } if (packageSettings.enabled == COMPONENT_ENABLED_STATE_DISABLED + || packageSettings.enabled == COMPONENT_ENABLED_STATE_DISABLED_USER || (packageSettings.pkg != null && !packageSettings.pkg.applicationInfo.enabled && packageSettings.enabled == COMPONENT_ENABLED_STATE_DEFAULT)) { return false; diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml index 3e7ca08..d5dcd4e 100644 --- a/tests/HwAccelerationTest/AndroidManifest.xml +++ b/tests/HwAccelerationTest/AndroidManifest.xml @@ -31,6 +31,15 @@ android:hardwareAccelerated="true"> <activity + android:name="SmallCircleActivity" + android:label="_SmallCircle"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + + <activity android:name="ClearActivity" android:label="_Clear"> <intent-filter> diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/SmallCircleActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/SmallCircleActivity.java new file mode 100644 index 0000000..8c02539 --- /dev/null +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/SmallCircleActivity.java @@ -0,0 +1,70 @@ +/* + * 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.test.hwui; + +import android.app.Activity; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Path; +import android.os.Bundle; +import android.view.View; +import android.widget.LinearLayout; + +@SuppressWarnings({"UnusedDeclaration"}) +public class SmallCircleActivity extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + final LinearLayout layout = new LinearLayout(this); + layout.setOrientation(LinearLayout.VERTICAL); + + View view = new PathView(this); + layout.addView(view, new LinearLayout.LayoutParams(PathView.SIZE, PathView.SIZE)); + view = new PathView(this); + view.setLayerType(View.LAYER_TYPE_SOFTWARE, null); + layout.addView(view, new LinearLayout.LayoutParams(PathView.SIZE, PathView.SIZE)); + + setContentView(layout); + } + + static class PathView extends View { + private static final int SIZE = 37; + private final Paint mPaint; + private final Path mPath; + + PathView(Context c) { + super(c); + + mPath = new Path(); + mPath.addCircle(SIZE * 0.5f, SIZE * 0.5f, SIZE * 0.275f, Path.Direction.CW); + mPath.addCircle(SIZE * 0.5f, SIZE * 0.5f, SIZE * 0.225f, Path.Direction.CCW); + + mPaint = new Paint(); + mPaint.setAntiAlias(true); + mPaint.setColor(0xffffffff); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + canvas.drawPath(mPath, mPaint); + } + } +} |