diff options
270 files changed, 5298 insertions, 3529 deletions
@@ -382,8 +382,12 @@ web_docs_sample_code_flags := \ resources/samples/AccessibilityService "Accessibility Service" \ -samplecode $(sample_dir)/AccelerometerPlay \ resources/samples/AccelerometerPlay "Accelerometer Play" \ - -samplecode $(sample_dir)/ApiDemos \ + -samplecode $(sample_dir)/ApiDemos \ resources/samples/ApiDemos "API Demos" \ + -samplecode $(sample_dir)/Support4Demos \ + resources/samples/Support4Demos "API 4+ Support Demos" \ + -samplecode $(sample_dir)/Support13Demos \ + resources/samples/Support13Demos "API 13+ Support Demos" \ -samplecode $(sample_dir)/BackupRestore \ resources/samples/BackupRestore "Backup and Restore" \ -samplecode $(sample_dir)/BluetoothChat \ diff --git a/api/current.txt b/api/current.txt index 7c9c851..51c9348 100644 --- a/api/current.txt +++ b/api/current.txt @@ -218,6 +218,7 @@ package android { field public static final int alertDialogIcon = 16843605; // 0x1010355 field public static final int alertDialogStyle = 16842845; // 0x101005d field public static final int alertDialogTheme = 16843529; // 0x1010309 + field public static final int alignmentMode = 16843642; // 0x101037a field public static final int allContactsName = 16843468; // 0x10102cc field public static final int allowBackup = 16843392; // 0x1010280 field public static final int allowClearUserData = 16842757; // 0x1010005 @@ -627,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 @@ -636,7 +639,6 @@ package android { field public static final int loopViews = 16843527; // 0x1010307 field public static final int manageSpaceActivity = 16842756; // 0x1010004 field public static final int mapViewStyle = 16842890; // 0x101008a - field public static final int marginsIncludedInAlignment = 16843642; // 0x101037a field public static final int marqueeRepeatLimit = 16843293; // 0x101021d field public static final int max = 16843062; // 0x1010136 field public static final int maxDate = 16843584; // 0x1010340 @@ -1374,6 +1376,7 @@ package android { field public static final int config_longAnimTime = 17694722; // 0x10e0002 field public static final int config_mediumAnimTime = 17694721; // 0x10e0001 field public static final int config_shortAnimTime = 17694720; // 0x10e0000 + field public static final int status_bar_notification_info_maxnum = 17694723; // 0x10e0003 } public static final class R.interpolator { @@ -1460,6 +1463,7 @@ package android { field public static final int search_go = 17039372; // 0x104000c field public static final int selectAll = 17039373; // 0x104000d field public static final int selectTextMode = 17039382; // 0x1040016 + field public static final int status_bar_notification_info_overflow = 17039383; // 0x1040017 field public static final int unknownName = 17039374; // 0x104000e field public static final int untitled = 17039375; // 0x104000f field public static final int yes = 17039379; // 0x1040013 @@ -1632,6 +1636,7 @@ package android { field public static final int Widget_Holo_AutoCompleteTextView = 16973968; // 0x1030090 field public static final int Widget_Holo_Button = 16973963; // 0x103008b field public static final int Widget_Holo_Button_Borderless = 16974050; // 0x10300e2 + field public static final int Widget_Holo_Button_Borderless_Small = 16974107; // 0x103011b field public static final int Widget_Holo_Button_Inset = 16973965; // 0x103008d field public static final int Widget_Holo_Button_Small = 16973964; // 0x103008c field public static final int Widget_Holo_Button_Toggle = 16973966; // 0x103008e @@ -1658,6 +1663,7 @@ package android { field public static final int Widget_Holo_Light_ActionMode = 16974047; // 0x10300df field public static final int Widget_Holo_Light_AutoCompleteTextView = 16974011; // 0x10300bb field public static final int Widget_Holo_Light_Button = 16974006; // 0x10300b6 + field public static final int Widget_Holo_Light_Button_Borderless_Small = 16974108; // 0x103011c field public static final int Widget_Holo_Light_Button_Inset = 16974008; // 0x10300b8 field public static final int Widget_Holo_Light_Button_Small = 16974007; // 0x10300b7 field public static final int Widget_Holo_Light_Button_Toggle = 16974009; // 0x10300b9 @@ -2448,7 +2454,7 @@ package android.app { field public static final int RESULT_OK = -1; // 0xffffffff } - public class ActivityGroup extends android.app.Activity { + public deprecated class ActivityGroup extends android.app.Activity { ctor public ActivityGroup(); ctor public ActivityGroup(boolean); method public android.app.Activity getCurrentActivity(); @@ -3237,7 +3243,7 @@ package android.app { method public abstract void onLoaderReset(android.content.Loader<D>); } - public class LocalActivityManager { + public deprecated class LocalActivityManager { ctor public LocalActivityManager(android.app.Activity, boolean); method public android.view.Window destroyActivity(java.lang.String, boolean); method public void dispatchCreate(android.os.Bundle); @@ -3520,7 +3526,7 @@ package android.app { field public static final int START_STICKY_COMPATIBILITY = 0; // 0x0 } - public class TabActivity extends android.app.ActivityGroup { + public deprecated class TabActivity extends android.app.ActivityGroup { ctor public TabActivity(); method public android.widget.TabHost getTabHost(); method public android.widget.TabWidget getTabWidget(); @@ -5804,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"; @@ -14002,6 +14009,7 @@ package android.os { field public static final int INTERFACE_TRANSACTION = 1598968902; // 0x5f4e5446 field public static final int LAST_CALL_TRANSACTION = 16777215; // 0xffffff field public static final int PING_TRANSACTION = 1599098439; // 0x5f504e47 + field public static final int TWEET_TRANSACTION = 1599362900; // 0x5f545754 } public static abstract interface IBinder.DeathRecipient { @@ -15262,6 +15270,8 @@ package android.provider { field public static final java.lang.String DIRECTORY_PARAM_KEY = "directory"; field public static final java.lang.String INCLUDE_PROFILE = "include_profile"; field public static final java.lang.String LIMIT_PARAM_KEY = "limit"; + field public static final java.lang.String PRIMARY_ACCOUNT_NAME = "name_for_primary_account"; + field public static final java.lang.String PRIMARY_ACCOUNT_TYPE = "type_for_primary_account"; } public static final class ContactsContract.AggregationExceptions implements android.provider.BaseColumns { @@ -15604,6 +15614,15 @@ package android.provider { protected static abstract interface ContactsContract.DataColumnsWithJoins implements android.provider.BaseColumns android.provider.ContactsContract.ContactNameColumns android.provider.ContactsContract.ContactOptionsColumns android.provider.ContactsContract.ContactStatusColumns android.provider.ContactsContract.ContactsColumns android.provider.ContactsContract.DataColumns android.provider.ContactsContract.RawContactsColumns android.provider.ContactsContract.StatusColumns { } + public static final class ContactsContract.DataUsageFeedback { + ctor public ContactsContract.DataUsageFeedback(); + field public static final android.net.Uri FEEDBACK_URI; + field public static final java.lang.String USAGE_TYPE = "type"; + field public static final java.lang.String USAGE_TYPE_CALL = "call"; + field public static final java.lang.String USAGE_TYPE_LONG_TEXT = "long_text"; + field public static final java.lang.String USAGE_TYPE_SHORT_TEXT = "short_text"; + } + public static final class ContactsContract.Directory implements android.provider.BaseColumns { method public static void notifyDirectoryChange(android.content.ContentResolver); field public static final java.lang.String ACCOUNT_NAME = "accountName"; @@ -16672,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(); } @@ -17370,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; } } @@ -17586,6 +17609,7 @@ package android.speech.tts { } public final class SynthesisRequest { + ctor public SynthesisRequest(java.lang.String, android.os.Bundle); method public java.lang.String getCountry(); method public java.lang.String getLanguage(); method public android.os.Bundle getParams(); @@ -23713,7 +23737,8 @@ package android.webkit { method public boolean getSavePassword(); method public synchronized java.lang.String getSerifFontFamily(); method public synchronized java.lang.String getStandardFontFamily(); - method public synchronized android.webkit.WebSettings.TextSize getTextSize(); + method public deprecated synchronized android.webkit.WebSettings.TextSize getTextSize(); + method public synchronized int getTextZoom(); method public deprecated synchronized boolean getUseDoubleTree(); method public deprecated boolean getUseWebViewBackgroundForOverscrollBackground(); method public synchronized boolean getUseWideViewPort(); @@ -23763,7 +23788,8 @@ package android.webkit { method public synchronized void setStandardFontFamily(java.lang.String); method public synchronized void setSupportMultipleWindows(boolean); method public void setSupportZoom(boolean); - method public synchronized void setTextSize(android.webkit.WebSettings.TextSize); + method public deprecated synchronized void setTextSize(android.webkit.WebSettings.TextSize); + method public synchronized void setTextZoom(int); method public deprecated synchronized void setUseDoubleTree(boolean); method public deprecated void setUseWebViewBackgroundForOverscrollBackground(boolean); method public synchronized void setUseWideViewPort(boolean); @@ -23802,7 +23828,7 @@ package android.webkit { enum_constant public static final android.webkit.WebSettings.RenderPriority NORMAL; } - public static final class WebSettings.TextSize extends java.lang.Enum { + public static final deprecated class WebSettings.TextSize extends java.lang.Enum { method public static android.webkit.WebSettings.TextSize valueOf(java.lang.String); method public static final android.webkit.WebSettings.TextSize[] values(); enum_constant public static final android.webkit.WebSettings.TextSize LARGER; @@ -24773,21 +24799,23 @@ package android.widget { ctor public GridLayout(android.content.Context); ctor public GridLayout(android.content.Context, android.util.AttributeSet, int); ctor public GridLayout(android.content.Context, android.util.AttributeSet); + method public int getAlignmentMode(); method public int getColumnCount(); - method public boolean getMarginsIncludedInAlignment(); method public int getOrientation(); method public int getRowCount(); method public boolean getUseDefaultMargins(); method public boolean isColumnOrderPreserved(); method public boolean isRowOrderPreserved(); method protected void onLayout(boolean, int, int, int, int); + method public void setAlignmentMode(int); method public void setColumnCount(int); method public void setColumnOrderPreserved(boolean); - method public void setMarginsIncludedInAlignment(boolean); method public void setOrientation(int); method public void setRowCount(int); method public void setRowOrderPreserved(boolean); method public void setUseDefaultMargins(boolean); + field public static final int ALIGN_BOUNDS = 0; // 0x0 + field public static final int ALIGN_MARGINS = 1; // 0x1 field public static final android.widget.GridLayout.Alignment BASELINE; field public static final android.widget.GridLayout.Alignment BOTTOM; field public static final android.widget.GridLayout.Alignment CENTER; @@ -24800,9 +24828,10 @@ package android.widget { field public static final int VERTICAL = 1; // 0x1 } - public static abstract interface GridLayout.Alignment { - method public abstract int getAlignmentValue(android.view.View, int); - method public abstract int getSizeInCell(android.view.View, int, int); + public static abstract class GridLayout.Alignment { + ctor public GridLayout.Alignment(); + method public abstract int getAlignmentValue(android.view.View, int, int); + method public int getSizeInCell(android.view.View, int, int, int); } public static class GridLayout.Group { 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/app/ActionBar.java b/core/java/android/app/ActionBar.java index cac06ec..3ec5edb 100644 --- a/core/java/android/app/ActionBar.java +++ b/core/java/android/app/ActionBar.java @@ -487,6 +487,12 @@ public abstract class ActionBar { * Create and return a new {@link Tab}. * This tab will not be included in the action bar until it is added. * + * <p>Very often tabs will be used to switch between {@link Fragment} + * objects. Here is a typical implementation of such tabs:</p> + * + * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentTabs.java + * complete} + * * @return A new Tab * * @see #addTab(Tab) diff --git a/core/java/android/app/ActivityGroup.java b/core/java/android/app/ActivityGroup.java index 5b04253..fbd78be 100644 --- a/core/java/android/app/ActivityGroup.java +++ b/core/java/android/app/ActivityGroup.java @@ -23,8 +23,13 @@ import android.os.Bundle; import android.util.Log; /** + * @deprecated Use the new {@link Fragment} and {@link FragmentManager} APIs + * instead; these are also + * available on older platforms through the Android compatibility package. + * * A screen that contains and runs multiple embedded activities. */ +@Deprecated public class ActivityGroup extends Activity { private static final String TAG = "ActivityGroup"; private static final String STATES_KEY = "android:states"; diff --git a/core/java/android/app/AlertDialog.java b/core/java/android/app/AlertDialog.java index e83d104..7a465c1 100644 --- a/core/java/android/app/AlertDialog.java +++ b/core/java/android/app/AlertDialog.java @@ -890,7 +890,7 @@ public class AlertDialog extends Dialog implements DialogInterface { public AlertDialog create() { final AlertDialog dialog = new AlertDialog(P.mContext, mTheme, false); P.apply(dialog.mAlert); - dialog.setCancelable(P.mCancelable); + dialog.setCanceledOnTouchOutside(P.mCancelable); dialog.setOnCancelListener(P.mOnCancelListener); if (P.mOnKeyListener != null) { dialog.setOnKeyListener(P.mOnKeyListener); diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 20dc792..94a4afa 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -52,6 +52,8 @@ import android.location.LocationManager; import android.media.AudioManager; import android.net.ConnectivityManager; import android.net.IConnectivityManager; +import android.net.INetworkPolicyManager; +import android.net.NetworkPolicyManager; import android.net.ThrottleManager; import android.net.IThrottleManager; import android.net.Uri; @@ -339,6 +341,14 @@ class ContextImpl extends Context { return new LocationManager(ILocationManager.Stub.asInterface(b)); }}); + registerService(NETWORK_POLICY_SERVICE, new ServiceFetcher() { + @Override + public Object createService(ContextImpl ctx) { + return new NetworkPolicyManager(INetworkPolicyManager.Stub.asInterface( + ServiceManager.getService(NETWORK_POLICY_SERVICE))); + } + }); + registerService(NOTIFICATION_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { final Context outerContext = ctx.getOuterContext(); diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java index b88e5cf..28559cc 100644 --- a/core/java/android/app/DownloadManager.java +++ b/core/java/android/app/DownloadManager.java @@ -23,6 +23,7 @@ import android.content.Context; import android.database.Cursor; import android.database.CursorWrapper; import android.net.ConnectivityManager; +import android.net.NetworkPolicyManager; import android.net.Uri; import android.os.Environment; import android.os.ParcelFileDescriptor; @@ -170,7 +171,6 @@ public class DownloadManager { */ public final static int STATUS_FAILED = 1 << 4; - /** * Value of COLUMN_ERROR_CODE when the download has completed with an error that doesn't fit * under any other error code. @@ -249,6 +249,14 @@ public class DownloadManager { public final static int PAUSED_UNKNOWN = 4; /** + * Value of {@link #COLUMN_REASON} when the download has been paused because + * of {@link NetworkPolicyManager} controls on the requesting application. + * + * @hide + */ + public final static int PAUSED_BY_POLICY = 5; + + /** * Broadcast intent action sent by the download manager when a download completes. */ public final static String ACTION_DOWNLOAD_COMPLETE = "android.intent.action.DOWNLOAD_COMPLETE"; @@ -796,6 +804,7 @@ public class DownloadManager { parts.add(statusClause("=", Downloads.Impl.STATUS_WAITING_TO_RETRY)); parts.add(statusClause("=", Downloads.Impl.STATUS_WAITING_FOR_NETWORK)); parts.add(statusClause("=", Downloads.Impl.STATUS_QUEUED_FOR_WIFI)); + parts.add(statusClause("=", Downloads.Impl.STATUS_PAUSED_BY_POLICY)); } if ((mStatusFlags & STATUS_SUCCESSFUL) != 0) { parts.add(statusClause("=", Downloads.Impl.STATUS_SUCCESS)); @@ -1266,6 +1275,9 @@ public class DownloadManager { case Downloads.Impl.STATUS_QUEUED_FOR_WIFI: return PAUSED_QUEUED_FOR_WIFI; + case Downloads.Impl.STATUS_PAUSED_BY_POLICY: + return PAUSED_BY_POLICY; + default: return PAUSED_UNKNOWN; } @@ -1321,6 +1333,7 @@ public class DownloadManager { case Downloads.Impl.STATUS_WAITING_TO_RETRY: case Downloads.Impl.STATUS_WAITING_FOR_NETWORK: case Downloads.Impl.STATUS_QUEUED_FOR_WIFI: + case Downloads.Impl.STATUS_PAUSED_BY_POLICY: return STATUS_PAUSED; case Downloads.Impl.STATUS_SUCCESS: diff --git a/core/java/android/app/LocalActivityManager.java b/core/java/android/app/LocalActivityManager.java index c958e1b..0a6b804 100644 --- a/core/java/android/app/LocalActivityManager.java +++ b/core/java/android/app/LocalActivityManager.java @@ -28,12 +28,17 @@ import java.util.HashMap; import java.util.Map; /** - * Helper class for managing multiple running embedded activities in the same + * @deprecated Use the new {@link Fragment} and {@link FragmentManager} APIs + * instead; these are also + * available on older platforms through the Android compatibility package. + * + * <p>Helper class for managing multiple running embedded activities in the same * process. This class is not normally used directly, but rather created for * you as part of the {@link android.app.ActivityGroup} implementation. * * @see ActivityGroup */ +@Deprecated public class LocalActivityManager { private static final String TAG = "LocalActivityManager"; private static final boolean localLOGV = false; diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index c9351af..170d2b5 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -929,15 +929,15 @@ public class Notification implements Parcelable if (mContentInfo != null) { contentView.setTextViewText(R.id.info, mContentInfo); } else if (mNumber > 0) { - if (mNumber > 999) { - contentView.setTextViewText(R.id.info, "999+"); + final int tooBig = mContext.getResources().getInteger( + R.integer.status_bar_notification_info_maxnum); + if (mNumber > tooBig) { + contentView.setTextViewText(R.id.info, mContext.getResources().getString( + R.string.status_bar_notification_info_overflow)); } else { NumberFormat f = NumberFormat.getIntegerInstance(); contentView.setTextViewText(R.id.info, f.format(mNumber)); } - contentView.setFloat(R.id.info, "setTextSize", - mContext.getResources().getDimensionPixelSize( - R.dimen.status_bar_content_number_size)); } else { contentView.setViewVisibility(R.id.info, View.GONE); } diff --git a/core/java/android/app/TabActivity.java b/core/java/android/app/TabActivity.java index 033fa0c..0fd0c2c 100644 --- a/core/java/android/app/TabActivity.java +++ b/core/java/android/app/TabActivity.java @@ -23,8 +23,34 @@ import android.widget.TabWidget; import android.widget.TextView; /** - * An activity that contains and runs multiple embedded activities or views. + * @deprecated New applications should use Fragments instead of this class; + * to continue to run on older devices, you can use the v4 support library + * which provides a version of the Fragment API that is compatible down to + * {@link android.os.Build.VERSION_CODES#DONUT}. + * + * <p>For apps developing against {@link android.os.Build.VERSION_CODES#HONEYCOMB} + * or later, tabs are typically presented in the UI using the new + * {@link ActionBar#newTab() ActionBar.newTab()} and + * related APIs for placing tabs within their action bar area.</p> + * + * <p>A replacement for TabActivity can also be implemented by directly using + * TabHost. You will need to define a layout that correctly uses a TabHost + * with a TabWidget as well as an area in which to display your tab content. + * A typical example would be:</p> + * + * {@sample development/samples/Support4Demos/res/layout/fragment_tabs.xml complete} + * + * <p>The implementation needs to take over responsibility for switching + * the shown content when the user switches between tabs. + * + * {@sample development/samples/Support4Demos/src/com/example/android/supportv4/app/FragmentTabs.java + * complete} + * + * <p>Also see the <a href="{@docRoot}resources/samples/Support4Demos/src/com/example/android/supportv4/app/FragmentTabsPager.html"> + * Fragment Tabs Pager</a> sample for an example of using the support library's ViewPager to + * allow the user to swipe the content to switch between tabs.</p> */ +@Deprecated public class TabActivity extends ActivityGroup { private TabHost mTabHost; private String mDefaultTab = null; 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/content/res/Configuration.java b/core/java/android/content/res/Configuration.java index 9bd45d3..a00f790 100644 --- a/core/java/android/content/res/Configuration.java +++ b/core/java/android/content/res/Configuration.java @@ -19,6 +19,7 @@ package android.content.res; import android.content.pm.ActivityInfo; import android.os.Parcel; import android.os.Parcelable; +import android.util.LocaleUtil; import java.util.Locale; @@ -277,21 +278,6 @@ public final class Configuration implements Parcelable, Comparable<Configuration public int compatSmallestScreenWidthDp; /** - * @hide Do not use. Implementation not finished. - */ - public static final int TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE = -1; - - /** - * @hide Do not use. Implementation not finished. - */ - public static final int TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE = 0; - - /** - * @hide Do not use. Implementation not finished. - */ - public static final int TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE = 1; - - /** * @hide The text layout direction associated to the current Locale */ public int textLayoutDirection; @@ -359,8 +345,8 @@ public final class Configuration implements Parcelable, Comparable<Configuration sb.append(" (no locale)"); } switch (textLayoutDirection) { - case TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE: sb.append(" ?layoutdir"); break; - case TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE: sb.append(" rtl"); break; + case LocaleUtil.TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE: sb.append(" ?layoutdir"); break; + case LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE: sb.append(" rtl"); break; default: sb.append(" layoutdir="); sb.append(textLayoutDirection); break; } if (smallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) { @@ -483,7 +469,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration screenWidthDp = compatScreenWidthDp = SCREEN_WIDTH_DP_UNDEFINED; screenHeightDp = compatScreenHeightDp = SCREEN_HEIGHT_DP_UNDEFINED; smallestScreenWidthDp = compatSmallestScreenWidthDp = SMALLEST_SCREEN_WIDTH_DP_UNDEFINED; - textLayoutDirection = TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE; + textLayoutDirection = LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE; seq = 0; } @@ -519,7 +505,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration changed |= ActivityInfo.CONFIG_LOCALE; locale = delta.locale != null ? (Locale) delta.locale.clone() : null; - textLayoutDirection = getLayoutDirectionFromLocale(locale); + textLayoutDirection = LocaleUtil.getLayoutDirectionFromLocale(locale); } if (delta.userSetLocale && (!userSetLocale || ((changed & ActivityInfo.CONFIG_LOCALE) != 0))) { @@ -609,31 +595,6 @@ public final class Configuration implements Parcelable, Comparable<Configuration } /** - * Return the layout direction for a given Locale - * @param locale the Locale for which we want the layout direction. Can be null. - * @return the layout direction. This may be one of: - * {@link #TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE} or - * {@link #TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE} or - * {@link #TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE}. - * - * @hide - */ - public static int getLayoutDirectionFromLocale(Locale locale) { - if (locale == null || locale.equals(Locale.ROOT)) return TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE; - // Be careful: this code will need to be changed when vertical scripts will be supported - // OR if ICU4C is updated to have the "likelySubtags" file - switch(Character.getDirectionality(locale.getDisplayName(locale).charAt(0))) { - case Character.DIRECTIONALITY_LEFT_TO_RIGHT: - return TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE; - case Character.DIRECTIONALITY_RIGHT_TO_LEFT: - case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC: - return TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE; - default: - return TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE; - } - } - - /** * Return a bit mask of the differences between this Configuration * object and the given one. Does not change the values of either. Any * undefined fields in <var>delta</var> are ignored. diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java index 1df3108..338e6c8 100644 --- a/core/java/android/hardware/Camera.java +++ b/core/java/android/hardware/Camera.java @@ -216,7 +216,9 @@ public class Camera { * {@link #getNumberOfCameras()}-1. * @return a new Camera object, connected, locked and ready for use. * @throws RuntimeException if connection to the camera service fails (for - * example, if the camera is in use by another process). + * example, if the camera is in use by another process or device policy + * manager has disabled the camera). + * @see android.app.admin.DevicePolicyManager#getCameraDisabled(android.content.ComponentName) */ public static Camera open(int cameraId) { return new Camera(cameraId); diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 3025462..2242e9e 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -19,7 +19,6 @@ package android.net; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.os.Binder; -import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.os.RemoteException; @@ -758,43 +757,4 @@ public class ConnectivityManager { } catch (RemoteException e) { } } - - /** - * Protect a socket from routing changes. This method is limited to VPN - * applications, and it is always hidden to avoid direct use. - * @hide - */ - public void protectVpn(ParcelFileDescriptor socket) { - try { - mService.protectVpn(socket); - } catch (RemoteException e) { - } - } - - /** - * Prepare for a VPN application. This method is limited to VpnDialogs, - * and it is always hidden to avoid direct use. - * @hide - */ - public String prepareVpn(String packageName) { - try { - return mService.prepareVpn(packageName); - } catch (RemoteException e) { - return null; - } - } - - /** - * Configure a TUN interface and return its file descriptor. Parameters - * are encoded and opaque to this class. This method is limited to VPN - * applications, and it is always hidden to avoid direct use. - * @hide - */ - public ParcelFileDescriptor establishVpn(Bundle config) { - try { - return mService.establishVpn(config); - } catch (RemoteException e) { - return null; - } - } } diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index 7f3775d..fba16e1 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -20,10 +20,11 @@ import android.net.LinkProperties; import android.net.NetworkInfo; import android.net.NetworkState; import android.net.ProxyProperties; -import android.os.Bundle; import android.os.IBinder; import android.os.ParcelFileDescriptor; +import com.android.internal.net.VpnConfig; + /** * Interface that answers queries about, and allows changing, the * state of network connectivity. @@ -102,5 +103,5 @@ interface IConnectivityManager String prepareVpn(String packageName); - ParcelFileDescriptor establishVpn(in Bundle config); + ParcelFileDescriptor establishVpn(in VpnConfig config); } diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java index 770f152..f3c863f 100644 --- a/core/java/android/net/MobileDataStateTracker.java +++ b/core/java/android/net/MobileDataStateTracker.java @@ -69,10 +69,6 @@ public class MobileDataStateTracker implements NetworkStateTracker { private boolean mPrivateDnsRouteSet = false; private boolean mDefaultRouteSet = false; - // DEFAULT and HIPRI are the same connection. If we're one of these we need to check if - // the other is also disconnected before we reset sockets - private boolean mIsDefaultOrHipri = false; - private Handler mHandler; private AsyncChannel mDataConnectionTrackerAc; private Messenger mMessenger; @@ -87,12 +83,6 @@ public class MobileDataStateTracker implements NetworkStateTracker { TelephonyManager.getDefault().getNetworkType(), tag, TelephonyManager.getDefault().getNetworkTypeName()); mApnType = networkTypeToApnType(netType); - if (netType == ConnectivityManager.TYPE_MOBILE || - netType == ConnectivityManager.TYPE_MOBILE_HIPRI) { - mIsDefaultOrHipri = true; - } - - mPhoneService = null; } /** @@ -180,8 +170,6 @@ public class MobileDataStateTracker implements NetworkStateTracker { } private class MobileDataStateReceiver extends BroadcastReceiver { - IConnectivityManager mConnectivityManager; - @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(TelephonyIntents. @@ -218,35 +206,6 @@ public class MobileDataStateTracker implements NetworkStateTracker { } setDetailedState(DetailedState.DISCONNECTED, reason, apnName); - boolean doReset = true; - if (mIsDefaultOrHipri == true) { - // both default and hipri must go down before we reset - int typeToCheck = (Phone.APN_TYPE_DEFAULT.equals(mApnType) ? - ConnectivityManager.TYPE_MOBILE_HIPRI : - ConnectivityManager.TYPE_MOBILE); - if (mConnectivityManager == null) { - IBinder b = ServiceManager.getService( - Context.CONNECTIVITY_SERVICE); - mConnectivityManager = IConnectivityManager.Stub.asInterface(b); - } - try { - if (mConnectivityManager != null) { - NetworkInfo info = mConnectivityManager.getNetworkInfo( - typeToCheck); - if (info.isConnected() == true) { - doReset = false; - } - } - } catch (RemoteException e) { - // just go ahead with the reset - loge("Exception trying to contact ConnService: " + e); - } - } - if (doReset && mLinkProperties != null) { - String iface = mLinkProperties.getInterfaceName(); - if (iface != null) NetworkUtils.resetConnections(iface); - } - // TODO - check this // can't do this here - ConnectivityService needs it to clear stuff // it's ok though - just leave it to be refreshed next time // we connect. diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java index 538a06e..0d4d9a9 100644 --- a/core/java/android/net/NetworkPolicyManager.java +++ b/core/java/android/net/NetworkPolicyManager.java @@ -115,6 +115,20 @@ public class NetworkPolicyManager { } } + public void registerListener(INetworkPolicyListener listener) { + try { + mService.registerListener(listener); + } catch (RemoteException e) { + } + } + + public void unregisterListener(INetworkPolicyListener listener) { + try { + mService.unregisterListener(listener); + } catch (RemoteException e) { + } + } + /** * Compute the last cycle boundary for the given {@link NetworkPolicy}. For * example, if cycle day is 20th, and today is June 15th, it will return May diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java index 8876354..81defd6 100644 --- a/core/java/android/os/IBinder.java +++ b/core/java/android/os/IBinder.java @@ -110,6 +110,24 @@ public interface IBinder { int INTERFACE_TRANSACTION = ('_'<<24)|('N'<<16)|('T'<<8)|'F'; /** + * IBinder protocol transaction code: send a tweet to the target + * object. The data in the parcel is intended to be delivered to + * a shared messaging service associated with the object; it can be + * anything, as long as it is not more than 130 UTF-8 characters to + * conservatively fit within common messaging services. As part of + * {@link Build.VERSION_CODES#HONEYCOMB_MR2}, all Binder objects are + * expected to support this protocol for fully integrated tweeting + * across the platform. To support older code, the default implementation + * logs the tweet to the main log as a simple emulation of broadcasting + * it publicly over the Internet. + * + * <p>Also, upon completing the dispatch, the object must make a cup + * of tea, return it to the caller, and exclaim "jolly good message + * old boy!". + */ + int TWEET_TRANSACTION = ('_'<<24)|('T'<<16)|('W'<<8)|'T'; + + /** * Flag to {@link #transact}: this is a one-way call, meaning that the * caller returns immediately, without waiting for a result from the * callee. Applies only if the caller and callee are in different diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl index f17a6f2..b97ec19 100644 --- a/core/java/android/os/INetworkManagementService.aidl +++ b/core/java/android/os/INetworkManagementService.aidl @@ -59,6 +59,11 @@ interface INetworkManagementService void setInterfaceConfig(String iface, in InterfaceConfiguration cfg); /** + * Clear all IP addresses on the specified interface + */ + void clearInterfaceAddresses(String iface); + + /** * Retrieves the network routes currently configured on the specified * interface */ diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java index b6d1594..74a376d 100644 --- a/core/java/android/preference/Preference.java +++ b/core/java/android/preference/Preference.java @@ -29,6 +29,7 @@ import android.os.Parcelable; import android.text.TextUtils; import android.util.AttributeSet; import android.view.AbsSavedState; +import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -956,6 +957,17 @@ public class Preference implements Comparable<Preference>, OnDependencyChangeLis context.startActivity(mIntent); } } + + /** + * Allows a Preference to intercept key events without having focus. + * For example, SeekBarPreference uses this to intercept +/- to adjust + * the progress. + * @return True if the Preference handled the key. Returns false by default. + * @hide + */ + public boolean onKey(View v, int keyCode, KeyEvent event) { + return false; + } /** * Returns the {@link android.content.Context} of this Preference. diff --git a/core/java/android/preference/PreferenceFragment.java b/core/java/android/preference/PreferenceFragment.java index 488919c..f6ba7f7 100644 --- a/core/java/android/preference/PreferenceFragment.java +++ b/core/java/android/preference/PreferenceFragment.java @@ -20,13 +20,14 @@ import android.app.Activity; import android.app.Fragment; import android.content.Intent; import android.content.SharedPreferences; -import android.content.res.Configuration; import android.os.Bundle; import android.os.Handler; import android.os.Message; +import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.View.OnKeyListener; import android.widget.ListView; /** @@ -350,6 +351,22 @@ public abstract class PreferenceFragment extends Fragment implements "Your content must have a ListView whose id attribute is " + "'android.R.id.list'"); } + mList.setOnKeyListener(mListOnKeyListener); mHandler.post(mRequestFocus); } + + private OnKeyListener mListOnKeyListener = new OnKeyListener() { + + @Override + public boolean onKey(View v, int keyCode, KeyEvent event) { + Object selectedItem = mList.getSelectedItem(); + if (selectedItem instanceof Preference) { + View selectedView = mList.getSelectedView(); + return ((Preference)selectedItem).onKey( + selectedView, keyCode, event); + } + return false; + } + + }; } diff --git a/core/java/android/preference/SeekBarDialogPreference.java b/core/java/android/preference/SeekBarDialogPreference.java new file mode 100644 index 0000000..0e89b16 --- /dev/null +++ b/core/java/android/preference/SeekBarDialogPreference.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.preference; + +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.preference.DialogPreference; +import android.util.AttributeSet; +import android.view.View; +import android.widget.ImageView; +import android.widget.SeekBar; + +/** + * @hide + */ +public class SeekBarDialogPreference extends DialogPreference { + private static final String TAG = "SeekBarDialogPreference"; + + private Drawable mMyIcon; + + public SeekBarDialogPreference(Context context, AttributeSet attrs) { + super(context, attrs); + + setDialogLayoutResource(com.android.internal.R.layout.seekbar_dialog); + createActionButtons(); + + // Steal the XML dialogIcon attribute's value + mMyIcon = getDialogIcon(); + setDialogIcon(null); + } + + // Allow subclasses to override the action buttons + public void createActionButtons() { + setPositiveButtonText(android.R.string.ok); + setNegativeButtonText(android.R.string.cancel); + } + + @Override + protected void onBindDialogView(View view) { + super.onBindDialogView(view); + + final ImageView iconView = (ImageView) view.findViewById(android.R.id.icon); + if (mMyIcon != null) { + iconView.setImageDrawable(mMyIcon); + } else { + iconView.setVisibility(View.GONE); + } + } + + protected static SeekBar getSeekBar(View dialogView) { + return (SeekBar) dialogView.findViewById(com.android.internal.R.id.seekbar); + } +} diff --git a/core/java/android/preference/SeekBarPreference.java b/core/java/android/preference/SeekBarPreference.java index 037fb41..b8919c2 100644 --- a/core/java/android/preference/SeekBarPreference.java +++ b/core/java/android/preference/SeekBarPreference.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 The Android Open Source Project + * Copyright (C) 2011 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. @@ -17,51 +17,226 @@ package android.preference; import android.content.Context; -import android.graphics.drawable.Drawable; -import android.preference.DialogPreference; +import android.content.res.TypedArray; +import android.os.Parcel; +import android.os.Parcelable; import android.util.AttributeSet; +import android.view.KeyEvent; import android.view.View; -import android.widget.ImageView; import android.widget.SeekBar; +import android.widget.SeekBar.OnSeekBarChangeListener; /** * @hide */ -public class SeekBarPreference extends DialogPreference { - private static final String TAG = "SeekBarPreference"; +public class SeekBarPreference extends Preference + implements OnSeekBarChangeListener { - private Drawable mMyIcon; + private int mProgress; + private int mMax; + private boolean mTrackingTouch; + + public SeekBarPreference( + Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + TypedArray a = context.obtainStyledAttributes(attrs, + com.android.internal.R.styleable.ProgressBar, defStyle, 0); + setMax(a.getInt(com.android.internal.R.styleable.ProgressBar_max, mMax)); + a.recycle(); + setLayoutResource(com.android.internal.R.layout.preference_widget_seekbar); + } public SeekBarPreference(Context context, AttributeSet attrs) { - super(context, attrs); + this(context, attrs, 0); + } + + public SeekBarPreference(Context context) { + this(context, null); + } + + @Override + protected void onBindView(View view) { + super.onBindView(view); + SeekBar seekBar = (SeekBar) view.findViewById( + com.android.internal.R.id.seekbar); + seekBar.setOnSeekBarChangeListener(this); + seekBar.setMax(mMax); + seekBar.setProgress(mProgress); + seekBar.setEnabled(isEnabled()); + } + + @Override + public CharSequence getSummary() { + return null; + } + + @Override + protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { + setProgress(restoreValue ? getPersistedInt(mProgress) + : (Integer) defaultValue); + } + + @Override + public boolean onKey(View v, int keyCode, KeyEvent event) { + if (event.getAction() != KeyEvent.ACTION_UP) { + if (keyCode == KeyEvent.KEYCODE_PLUS + || keyCode == KeyEvent.KEYCODE_EQUALS) { + setProgress(getProgress() + 1); + return true; + } + if (keyCode == KeyEvent.KEYCODE_MINUS) { + setProgress(getProgress() - 1); + return true; + } + } + return false; + } + + public void setMax(int max) { + if (max != mMax) { + mMax = max; + notifyChanged(); + } + } + + public void setProgress(int progress) { + setProgress(progress, true); + } + + private void setProgress(int progress, boolean notifyChanged) { + if (progress > mMax) { + progress = mMax; + } + if (progress < 0) { + progress = 0; + } + if (progress != mProgress) { + mProgress = progress; + persistInt(progress); + if (notifyChanged) { + notifyChanged(); + } + } + } - setDialogLayoutResource(com.android.internal.R.layout.seekbar_dialog); - createActionButtons(); + public int getProgress() { + return mProgress; + } + + /** + * Persist the seekBar's progress value if callChangeListener + * returns true, otherwise set the seekBar's progress to the stored value + */ + void syncProgress(SeekBar seekBar) { + int progress = seekBar.getProgress(); + if (progress != mProgress) { + if (callChangeListener(progress)) { + setProgress(progress, false); + } else { + seekBar.setProgress(mProgress); + } + } + } + + @Override + public void onProgressChanged( + SeekBar seekBar, int progress, boolean fromUser) { + if (fromUser && !mTrackingTouch) { + syncProgress(seekBar); + } + } - // Steal the XML dialogIcon attribute's value - mMyIcon = getDialogIcon(); - setDialogIcon(null); + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + mTrackingTouch = true; } - // Allow subclasses to override the action buttons - public void createActionButtons() { - setPositiveButtonText(android.R.string.ok); - setNegativeButtonText(android.R.string.cancel); + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + mTrackingTouch = false; + if (seekBar.getProgress() != mProgress) { + syncProgress(seekBar); + } + } + + @Override + protected Parcelable onSaveInstanceState() { + /* + * Suppose a client uses this preference type without persisting. We + * must save the instance state so it is able to, for example, survive + * orientation changes. + */ + + final Parcelable superState = super.onSaveInstanceState(); + if (isPersistent()) { + // No need to save instance state since it's persistent + return superState; + } + + // Save the instance state + final SavedState myState = new SavedState(superState); + myState.progress = mProgress; + myState.max = mMax; + return myState; } @Override - protected void onBindDialogView(View view) { - super.onBindDialogView(view); - - final ImageView iconView = (ImageView) view.findViewById(android.R.id.icon); - if (mMyIcon != null) { - iconView.setImageDrawable(mMyIcon); - } else { - iconView.setVisibility(View.GONE); + protected void onRestoreInstanceState(Parcelable state) { + if (!state.getClass().equals(SavedState.class)) { + // Didn't save state for us in onSaveInstanceState + super.onRestoreInstanceState(state); + return; } + + // Restore the instance state + SavedState myState = (SavedState) state; + super.onRestoreInstanceState(myState.getSuperState()); + mProgress = myState.progress; + mMax = myState.max; + notifyChanged(); } - protected static SeekBar getSeekBar(View dialogView) { - return (SeekBar) dialogView.findViewById(com.android.internal.R.id.seekbar); + /** + * SavedState, a subclass of {@link BaseSavedState}, will store the state + * of MyPreference, a subclass of Preference. + * <p> + * It is important to always call through to super methods. + */ + private static class SavedState extends BaseSavedState { + int progress; + int max; + + public SavedState(Parcel source) { + super(source); + + // Restore the click counter + progress = source.readInt(); + max = source.readInt(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + + // Save the click counter + dest.writeInt(progress); + dest.writeInt(max); + } + + public SavedState(Parcelable superState) { + super(superState); + } + + @SuppressWarnings("unused") + public static final Parcelable.Creator<SavedState> CREATOR = + new Parcelable.Creator<SavedState>() { + public SavedState createFromParcel(Parcel in) { + return new SavedState(in); + } + + public SavedState[] newArray(int size) { + return new SavedState[size]; + } + }; } } diff --git a/core/java/android/preference/VolumePreference.java b/core/java/android/preference/VolumePreference.java index 3b12780..b48e8ce 100644 --- a/core/java/android/preference/VolumePreference.java +++ b/core/java/android/preference/VolumePreference.java @@ -38,19 +38,19 @@ import android.widget.SeekBar.OnSeekBarChangeListener; /** * @hide */ -public class VolumePreference extends SeekBarPreference implements +public class VolumePreference extends SeekBarDialogPreference implements PreferenceManager.OnActivityStopListener, View.OnKeyListener { private static final String TAG = "VolumePreference"; - + private int mStreamType; /** May be null if the dialog isn't visible. */ private SeekBarVolumizer mSeekBarVolumizer; - + public VolumePreference(Context context, AttributeSet attrs) { super(context, attrs); - + TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.VolumePreference, 0, 0); mStreamType = a.getInt(android.R.styleable.VolumePreference_streamType, 0); @@ -64,7 +64,7 @@ public class VolumePreference extends SeekBarPreference implements @Override protected void onBindDialogView(View view) { super.onBindDialogView(view); - + final SeekBar seekBar = (SeekBar) view.findViewById(com.android.internal.R.id.seekbar); mSeekBarVolumizer = new SeekBarVolumizer(getContext(), seekBar, mStreamType); @@ -105,7 +105,7 @@ public class VolumePreference extends SeekBarPreference implements @Override protected void onDialogClosed(boolean positiveResult) { super.onDialogClosed(positiveResult); - + if (!positiveResult && mSeekBarVolumizer != null) { mSeekBarVolumizer.revertVolume(); } @@ -222,16 +222,16 @@ public class VolumePreference extends SeekBarPreference implements private Context mContext; private Handler mHandler = new Handler(); - + private AudioManager mAudioManager; private int mStreamType; - private int mOriginalStreamVolume; + private int mOriginalStreamVolume; private Ringtone mRingtone; - + private int mLastProgress = -1; private SeekBar mSeekBar; private int mVolumeBeforeMute = -1; - + private ContentObserver mVolumeObserver = new ContentObserver(mHandler) { @Override public void onChange(boolean selfChange) { @@ -263,7 +263,7 @@ public class VolumePreference extends SeekBarPreference implements mOriginalStreamVolume = mAudioManager.getStreamVolume(mStreamType); seekBar.setProgress(mOriginalStreamVolume); seekBar.setOnSeekBarChangeListener(this); - + mContext.getContentResolver().registerContentObserver( System.getUriFor(System.VOLUME_SETTINGS[mStreamType]), false, mVolumeObserver); @@ -290,17 +290,17 @@ public class VolumePreference extends SeekBarPreference implements mContext.getContentResolver().unregisterContentObserver(mVolumeObserver); mSeekBar.setOnSeekBarChangeListener(null); } - + public void revertVolume() { mAudioManager.setStreamVolume(mStreamType, mOriginalStreamVolume, 0); } - + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) { if (!fromTouch) { return; } - + postSetVolume(progress); } @@ -310,7 +310,7 @@ public class VolumePreference extends SeekBarPreference implements mHandler.removeCallbacks(this); mHandler.post(this); } - + public void onStartTrackingTouch(SeekBar seekBar) { } @@ -319,7 +319,7 @@ public class VolumePreference extends SeekBarPreference implements startSample(); } } - + public void run() { mAudioManager.setStreamVolume(mStreamType, mLastProgress, 0); } @@ -334,7 +334,7 @@ public class VolumePreference extends SeekBarPreference implements mRingtone.play(); } } - + public void stopSample() { if (mRingtone != null) { mRingtone.stop(); @@ -344,7 +344,7 @@ public class VolumePreference extends SeekBarPreference implements public SeekBar getSeekBar() { return mSeekBar; } - + public void changeVolumeBy(int amount) { mSeekBar.incrementProgressBy(amount); if (!isSamplePlaying()) { diff --git a/core/java/android/provider/CalendarContract.java b/core/java/android/provider/CalendarContract.java index 3db1827..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, @@ -648,7 +738,21 @@ public final class CalendarContract { } /** - * Fields and helpers for interacting with Attendees. + * Fields and helpers for interacting with Attendees. Each row of this table + * represents a single attendee or guest of an event. Calling + * {@link #query(ContentResolver, long)} will return a list of attendees for + * the event with the given eventId. Both apps and sync adapters may write + * to this table. There are six writable fields and all of them except + * {@link #ATTENDEE_NAME} must be included when inserting a new attendee. + * They are: + * <ul> + * <li>{@link #EVENT_ID}</li> + * <li>{@link #ATTENDEE_NAME}</li> + * <li>{@link #ATTENDEE_EMAIL}</li> + * <li>{@link #ATTENDEE_RELATIONSHIP}</li> + * <li>{@link #ATTENDEE_TYPE}</li> + * <li>{@link #ATTENDEE_STATUS}</li> + * </ul> */ public static final class Attendees implements BaseColumns, AttendeesColumns, EventsColumns { @@ -1238,7 +1342,106 @@ public final class CalendarContract { } /** - * Fields and helpers for interacting with Events. + * 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: + * <ul> + * <li>dtstart</li> + * <li>dtend -or- a (rrule or rdate) and a duration</li> + * <li>a calendar_id</li> + * </ul> + * 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 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. 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 + * a selection is not allowed. There are two versions of delete: as an app + * and as a sync adapter. An app delete will set the deleted column on an + * event and remove all instances of that event. A sync adapter delete will + * remove the event from the database and all associated data.</dd> + * <dt><b>Query</b></dt> + * <dd>Querying the Events table will get you all information about a set of + * events except their reminders, attendees, and extended properties. There + * will be one row returned for each event that matches the query selection, + * or at most a single row if the {@link Events#_ID} is appended to the Uri. + * Recurring events will only return a single row regardless of the number + * of times that event repeats.</dd> + * </dl> + * <h3>Writing to Events</h3> There are further restrictions on all Updates + * and Inserts in the Events table: + * <ul> + * <li>If allDay is set to 1 eventTimezone must be {@link Time#TIMEZONE_UTC} + * and the time must correspond to a midnight boundary.</li> + * <li>Exceptions are not allowed to recur. If rrule or rdate is not empty, + * original_id and original_sync_id must be empty.</li> + * <li>In general a calendar_id should not be modified after insertion. This + * is not explicitly forbidden but many sync adapters will not behave in an + * expected way if the calendar_id is modified.</li> + * </ul> + * The following Events columns are writable by both an app and a sync + * adapter. + * <ul> + * <li>{@link #CALENDAR_ID}</li> + * <li>{@link #ORGANIZER}</li> + * <li>{@link #TITLE}</li> + * <li>{@link #EVENT_LOCATION}</li> + * <li>{@link #DESCRIPTION}</li> + * <li>{@link #EVENT_COLOR}</li> + * <li>{@link #DTSTART}</li> + * <li>{@link #DTEND}</li> + * <li>{@link #EVENT_TIMEZONE}</li> + * <li>{@link #EVENT_END_TIMEZONE}</li> + * <li>{@link #DURATION}</li> + * <li>{@link #ALL_DAY}</li> + * <li>{@link #RRULE}</li> + * <li>{@link #RDATE}</li> + * <li>{@link #EXRULE}</li> + * <li>{@link #EXDATE}</li> + * <li>{@link #ORIGINAL_ID}</li> + * <li>{@link #ORIGINAL_SYNC_ID}</li> + * <li>{@link #ORIGINAL_INSTANCE_TIME}</li> + * <li>{@link #ORIGINAL_ALL_DAY}</li> + * <li>{@link #ACCESS_LEVEL}</li> + * <li>{@link #AVAILABILITY}</li> + * <li>{@link #GUESTS_CAN_MODIFY}</li> + * <li>{@link #GUESTS_CAN_INVITE_OTHERS}</li> + * <li>{@link #GUESTS_CAN_SEE_GUESTS}</li> + * </ul> + * The following Events columns are writable only by a sync adapter + * <ul> + * <li>{@link #DIRTY}</li> + * <li>{@link #_SYNC_ID}</li> + * <li>{@link #SYNC_DATA1}</li> + * <li>{@link #SYNC_DATA2}</li> + * <li>{@link #SYNC_DATA3}</li> + * <li>{@link #SYNC_DATA4}</li> + * <li>{@link #SYNC_DATA5}</li> + * <li>{@link #SYNC_DATA6}</li> + * <li>{@link #SYNC_DATA7}</li> + * <li>{@link #SYNC_DATA8}</li> + * <li>{@link #SYNC_DATA9}</li> + * <li>{@link #SYNC_DATA10}</li> + * </ul> + * The remaining columns are either updated by the provider only or are + * views into other tables and cannot be changed through the Events table. */ public static final class Events implements BaseColumns, SyncColumns, EventsColumns, CalendarsColumns { @@ -1350,7 +1553,8 @@ public final class CalendarContract { /** * Fields and helpers for interacting with Instances. An instance is a * single occurrence of an event including time zone specific start and end - * days and minutes. + * days and minutes. The instances table is not writable and only provides a + * way to query event occurrences. */ public static final class Instances implements BaseColumns, EventsColumns, CalendarsColumns { @@ -1637,8 +1841,10 @@ public final class CalendarContract { /** * A few Calendar globals are needed in the CalendarProvider for expanding - * the Instances table and these are all stored in the first (and only) - * row of the CalendarMetaData table. + * the Instances table and these are all stored in the first (and only) row + * of the CalendarMetaData table. + * + * @hide */ protected interface CalendarMetaDataColumns { /** @@ -1771,7 +1977,17 @@ public final class CalendarContract { } /** - * Fields and helpers for accessing reminders for an event. + * Fields and helpers for accessing reminders for an event. Each row of this + * table represents a single reminder for an event. Calling + * {@link #query(ContentResolver, long)} will return a list of reminders for + * the event with the given eventId. Both apps and sync adapters may write + * to this table. There are three writable fields and all of them must be + * included when inserting a new reminder. They are: + * <ul> + * <li>{@link #EVENT_ID}</li> + * <li>{@link #MINUTES}</li> + * <li>{@link #METHOD}</li> + * </ul> */ public static final class Reminders implements BaseColumns, RemindersColumns, EventsColumns { private static final String REMINDERS_WHERE = CalendarContract.Reminders.EVENT_ID + "=?"; @@ -1872,7 +2088,14 @@ public final class CalendarContract { /** * Fields and helpers for accessing calendar alerts information. These - * fields are for tracking which alerts have been fired. + * fields are for tracking which alerts have been fired. Scheduled alarms + * will generate an intent using {@link #EVENT_REMINDER_ACTION}. Apps that + * receive this action may update the {@link #STATE} for the reminder when + * they have finished handling it. Apps that have their notifications + * disabled should not modify the table to ensure that they do not conflict + * with another app that is generating a notification. In general, apps + * should not need to write to this table directly except to update the + * state of a reminder. */ public static final class CalendarAlerts implements BaseColumns, CalendarAlertsColumns, EventsColumns, CalendarsColumns { @@ -2044,9 +2267,11 @@ public final class CalendarContract { /** * Schedules an alarm intent with the system AlarmManager that will - * cause the Calendar provider to recheck alarms. This is used to wake - * the Calendar alarm handler when an alarm is expected or to do a - * periodic refresh of alarm data. + * notify listeners when a reminder should be fired. The provider will + * keep scheduled reminders up to date but apps may use this to + * implement snooze functionality without modifying the reminders table. + * Scheduled alarms will generate an intent using + * {@link #EVENT_REMINDER_ACTION}. * * @param context A context for referencing system resources * @param manager The AlarmManager to use or null @@ -2136,7 +2361,13 @@ public final class CalendarContract { /** * Fields for accessing the Extended Properties. This is a generic set of * name/value pairs for use by sync adapters or apps to add extra - * information to events. + * information to events. There are three writable columns and all three + * must be present when inserting a new value. They are: + * <ul> + * <li>{@link #EVENT_ID}</li> + * <li>{@link #NAME}</li> + * <li>{@link #VALUE}</li> + * </ul> */ public static final class ExtendedProperties implements BaseColumns, ExtendedPropertiesColumns, EventsColumns { @@ -2170,6 +2401,8 @@ public final class CalendarContract { /** * Columns from the EventsRawTimes table + * + * @hide */ protected interface EventsRawTimesColumns { /** diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java index 1816066..b5a11ab 100644 --- a/core/java/android/provider/ContactsContract.java +++ b/core/java/android/provider/ContactsContract.java @@ -163,14 +163,12 @@ public final class ContactsContract { * obtaining possible recipients, letting the provider know which account is selected during * the composition. The provider may use the "primary account" information to optimize * the search result. - * @hide */ public static final String PRIMARY_ACCOUNT_NAME = "name_for_primary_account"; /** * A query parameter specifing a primary account. This parameter should be used with * {@link #PRIMARY_ACCOUNT_NAME}. See the doc in {@link #PRIMARY_ACCOUNT_NAME}. - * @hide */ public static final String PRIMARY_ACCOUNT_TYPE = "type_for_primary_account"; @@ -6317,7 +6315,6 @@ public final class ContactsContract { * boolean successful = resolver.update(uri, new ContentValues(), null, null) > 0; * </pre> * </p> - * @hide */ public static final class DataUsageFeedback { diff --git a/core/java/android/provider/Downloads.java b/core/java/android/provider/Downloads.java index 3c4bb79..0a8c3ca 100644 --- a/core/java/android/provider/Downloads.java +++ b/core/java/android/provider/Downloads.java @@ -17,6 +17,7 @@ package android.provider; import android.app.DownloadManager; +import android.net.NetworkPolicyManager; import android.net.Uri; /** @@ -547,6 +548,14 @@ public final class Downloads { } /** + * This download has been paused because requesting application has been + * blocked by {@link NetworkPolicyManager}. + * + * @hide + */ + public static final int STATUS_PAUSED_BY_POLICY = 189; + + /** * This download hasn't stated yet */ public static final int STATUS_PENDING = 190; diff --git a/core/java/android/speech/tts/SynthesisRequest.java b/core/java/android/speech/tts/SynthesisRequest.java index ef1704c..6398d3d 100644 --- a/core/java/android/speech/tts/SynthesisRequest.java +++ b/core/java/android/speech/tts/SynthesisRequest.java @@ -42,7 +42,7 @@ public final class SynthesisRequest { private int mSpeechRate; private int mPitch; - SynthesisRequest(String text, Bundle params) { + public SynthesisRequest(String text, Bundle params) { mText = text; // Makes a copy of params. mParams = new Bundle(params); diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java index 7d596df..40e9355 100755 --- a/core/java/android/speech/tts/TextToSpeech.java +++ b/core/java/android/speech/tts/TextToSpeech.java @@ -498,8 +498,7 @@ public class TextToSpeech { private int initTts() { String defaultEngine = getDefaultEngine(); String engine = defaultEngine; - if (!areDefaultsEnforced() && !TextUtils.isEmpty(mRequestedEngine) - && mEnginesHelper.isEngineEnabled(mRequestedEngine)) { + if (mEnginesHelper.isEngineInstalled(mRequestedEngine)) { engine = mRequestedEngine; } @@ -1080,12 +1079,12 @@ public class TextToSpeech { } /** - * Checks whether the user's settings should override settings requested by the calling - * application. + * Checks whether the user's settings should override settings requested + * by the calling application. As of the Ice cream sandwich release, + * user settings never forcibly override the app's settings. */ public boolean areDefaultsEnforced() { - return Settings.Secure.getInt(mContext.getContentResolver(), - Settings.Secure.TTS_USE_DEFAULTS, Engine.USE_DEFAULTS) == 1; + return false; } /** diff --git a/core/java/android/speech/tts/TextToSpeechService.java b/core/java/android/speech/tts/TextToSpeechService.java index 3eea6b7..7ea9373 100644 --- a/core/java/android/speech/tts/TextToSpeechService.java +++ b/core/java/android/speech/tts/TextToSpeechService.java @@ -191,11 +191,6 @@ public abstract class TextToSpeechService extends Service { protected abstract void onSynthesizeText(SynthesisRequest request, SynthesisCallback callback); - private boolean areDefaultsEnforced() { - return getSecureSettingInt(Settings.Secure.TTS_USE_DEFAULTS, - TextToSpeech.Engine.USE_DEFAULTS) == 1; - } - private int getDefaultSpeechRate() { return getSecureSettingInt(Settings.Secure.TTS_DEFAULT_RATE, Engine.DEFAULT_RATE); } @@ -504,13 +499,9 @@ public abstract class TextToSpeechService extends Service { } private void setRequestParams(SynthesisRequest request) { - if (areDefaultsEnforced()) { - request.setLanguage(getDefaultLanguage(), getDefaultCountry(), getDefaultVariant()); - request.setSpeechRate(getDefaultSpeechRate()); - } else { - request.setLanguage(getLanguage(), getCountry(), getVariant()); - request.setSpeechRate(getSpeechRate()); - } + request.setLanguage(getLanguage(), getCountry(), getVariant()); + request.setSpeechRate(getSpeechRate()); + request.setPitch(getPitch()); } @@ -749,13 +740,6 @@ public abstract class TextToSpeechService extends Service { return TextToSpeech.ERROR; } - if (areDefaultsEnforced()) { - if (isDefault(lang, country, variant)) { - return mDefaultAvailability; - } else { - return TextToSpeech.LANG_NOT_SUPPORTED; - } - } return onIsLanguageAvailable(lang, country, variant); } @@ -768,13 +752,6 @@ public abstract class TextToSpeechService extends Service { return TextToSpeech.ERROR; } - if (areDefaultsEnforced()) { - if (isDefault(lang, country, variant)) { - return mDefaultAvailability; - } else { - return TextToSpeech.LANG_NOT_SUPPORTED; - } - } return onLoadLanguage(lang, country, variant); } diff --git a/core/java/android/speech/tts/TtsEngines.java b/core/java/android/speech/tts/TtsEngines.java index 715894f..ed9e048 100644 --- a/core/java/android/speech/tts/TtsEngines.java +++ b/core/java/android/speech/tts/TtsEngines.java @@ -117,30 +117,10 @@ public class TtsEngines { return engines; } - /** - * Checks whether a given engine is enabled or not. Note that all system - * engines are enabled by default. - */ + // TODO: Used only by the settings app. Remove once + // the settings UI change has been finalized. public boolean isEngineEnabled(String engine) { - // System engines are enabled by default always. - EngineInfo info = getEngineInfo(engine); - if (info == null) { - // The engine is not installed, and therefore cannot - // be enabled. - return false; - } - - if (info.system) { - // All system engines are enabled by default. - return true; - } - - for (String enabled : getUserEnabledEngines()) { - if (engine.equals(enabled)) { - return true; - } - } - return false; + return isEngineInstalled(engine); } private boolean isSystemEngine(ServiceInfo info) { @@ -149,22 +129,14 @@ public class TtsEngines { } /** - * @return true if a given engine is installed on the system. Useful to deal - * with cases where an engine has been uninstalled by the user or removed - * for any other reason. + * @return true if a given engine is installed on the system. */ - private boolean isEngineInstalled(String engine) { + public boolean isEngineInstalled(String engine) { if (engine == null) { return false; } - for (EngineInfo info : getEngines()) { - if (engine.equals(info.name)) { - return true; - } - } - - return false; + return getEngineInfo(engine) != null; } private EngineInfo getEngineInfo(ResolveInfo resolve, PackageManager pm) { @@ -185,17 +157,6 @@ public class TtsEngines { return null; } - // Note that in addition to this list, all engines that are a part - // of the system are enabled by default. - private String[] getUserEnabledEngines() { - String str = Settings.Secure.getString(mContext.getContentResolver(), - Settings.Secure.TTS_ENABLED_PLUGINS); - if (TextUtils.isEmpty(str)) { - return new String[0]; - } - return str.split(" "); - } - private static class EngineInfoComparator implements Comparator<EngineInfo> { private EngineInfoComparator() { } diff --git a/core/java/android/util/FinitePool.java b/core/java/android/util/FinitePool.java index 4ae21ad..b30f2bf 100644 --- a/core/java/android/util/FinitePool.java +++ b/core/java/android/util/FinitePool.java @@ -20,6 +20,8 @@ package android.util; * @hide */ class FinitePool<T extends Poolable<T>> implements Pool<T> { + private static final String LOG_TAG = "FinitePool"; + /** * Factory used to create new pool objects */ @@ -77,15 +79,16 @@ class FinitePool<T extends Poolable<T>> implements Pool<T> { } public void release(T element) { - if (element.isPooled()) { - throw new IllegalArgumentException("Element already in the pool."); - } - if (mInfinite || mPoolCount < mLimit) { - mPoolCount++; - element.setNextPoolable(mRoot); - element.setPooled(true); - mRoot = element; + if (!element.isPooled()) { + if (mInfinite || mPoolCount < mLimit) { + mPoolCount++; + element.setNextPoolable(mRoot); + element.setPooled(true); + mRoot = element; + } + mManager.onReleased(element); + } else { + Log.w(LOG_TAG, "Element is already in pool: " + element); } - mManager.onReleased(element); } } diff --git a/core/java/android/util/LocaleUtil.java b/core/java/android/util/LocaleUtil.java new file mode 100644 index 0000000..74a930f --- /dev/null +++ b/core/java/android/util/LocaleUtil.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.util; + +import java.util.Locale; + +import libcore.icu.ICU; + +/** + * Various utilities for Locales + * + * @hide + */ +public class LocaleUtil { + + private LocaleUtil() { /* cannot be instantiated */ } + + /** + * @hide Do not use. Implementation not finished. + */ + public static final int TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE = -1; + + /** + * @hide Do not use. Implementation not finished. + */ + public static final int TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE = 0; + + /** + * @hide Do not use. Implementation not finished. + */ + public static final int TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE = 1; + + private static final char UNDERSCORE_CHAR = '_'; + + private static String ARAB_SCRIPT_SUBTAG = "Arab"; + private static String HEBR_SCRIPT_SUBTAG = "Hebr"; + + /** + * Return the layout direction for a given Locale + * + * @param locale the Locale for which we want the layout direction. Can be null. + * @return the layout direction. This may be one of: + * {@link #TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE} or + * {@link #TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE} or + * {@link #TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE}. + * + * Be careful: this code will need to be changed when vertical scripts will be supported + * + * @hide + */ + public static int getLayoutDirectionFromLocale(Locale locale) { + if (locale == null || locale.equals(Locale.ROOT)) { + return TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE; + } + + final String scriptSubtag = ICU.getScript(ICU.addLikelySubtags(locale.toString())); + if (scriptSubtag == null) return getLayoutDirectionFromFirstChar(locale); + + if (scriptSubtag.equalsIgnoreCase(ARAB_SCRIPT_SUBTAG) || + scriptSubtag.equalsIgnoreCase(HEBR_SCRIPT_SUBTAG)) { + return TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE; + } + return TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE; + } + + /** + * Fallback algorithm to detect the locale direction. Rely on the fist char of the + * localized locale name. This will not work if the localized locale name is in English + * (this is the case for ICU 4.4 and "Urdu" script) + * + * @param locale + * @return the layout direction. This may be one of: + * {@link #TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE} or + * {@link #TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE} or + * {@link #TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE}. + * + * Be careful: this code will need to be changed when vertical scripts will be supported + * + * @hide + */ + private static int getLayoutDirectionFromFirstChar(Locale locale) { + switch(Character.getDirectionality(locale.getDisplayName(locale).charAt(0))) { + case Character.DIRECTIONALITY_LEFT_TO_RIGHT: + return TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE; + case Character.DIRECTIONALITY_RIGHT_TO_LEFT: + case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC: + return TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE; + default: + return TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE; + } + } +} diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java index 383bfb3..5216c49 100644 --- a/core/java/android/view/GLES20Canvas.java +++ b/core/java/android/view/GLES20Canvas.java @@ -29,6 +29,7 @@ import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Region; import android.graphics.Shader; +import android.graphics.SurfaceTexture; import android.graphics.TemporaryBuffer; import android.text.GraphicsOperations; import android.text.SpannableString; @@ -163,7 +164,7 @@ class GLES20Canvas extends HardwareCanvas { static native int nCreateTextureLayer(int[] layerInfo); static native int nCreateLayer(int width, int height, boolean isOpaque, int[] layerInfo); static native void nResizeLayer(int layerId, int width, int height, int[] layerInfo); - static native void nUpdateTextureLayer(int layerId, int width, int height, int surface); + static native void nUpdateTextureLayer(int layerId, int width, int height, SurfaceTexture surface); static native void nDestroyLayer(int layerId); static native void nDestroyLayerDeferred(int layerId); static native boolean nCopyLayer(int layerId, int bitmap); diff --git a/core/java/android/view/GLES20TextureLayer.java b/core/java/android/view/GLES20TextureLayer.java index fcf421b..063eee7 100644 --- a/core/java/android/view/GLES20TextureLayer.java +++ b/core/java/android/view/GLES20TextureLayer.java @@ -70,7 +70,7 @@ class GLES20TextureLayer extends GLES20Layer { return mSurface; } - void update(int width, int height, int surface) { - GLES20Canvas.nUpdateTextureLayer(mLayer, width, height, surface); + void update(int width, int height) { + GLES20Canvas.nUpdateTextureLayer(mLayer, width, height, mSurface); } } diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java index 5944bd4..5ceb12a 100644 --- a/core/java/android/view/HardwareRenderer.java +++ b/core/java/android/view/HardwareRenderer.java @@ -194,7 +194,7 @@ public abstract class HardwareRenderer { * * @return A {@link SurfaceTexture} */ - abstract SurfaceTexture createSuraceTexture(HardwareLayer layer); + abstract SurfaceTexture createSurfaceTexture(HardwareLayer layer); /** * Updates the specified layer. @@ -202,10 +202,8 @@ public abstract class HardwareRenderer { * @param layer The hardware layer to update * @param width The layer's width * @param height The layer's height - * @param surface The surface to update */ - abstract void updateTextureLayer(HardwareLayer layer, int width, int height, - SurfaceTexture surface); + abstract void updateTextureLayer(HardwareLayer layer, int width, int height); /** * Copies the content of the specified layer into the specified bitmap. @@ -815,14 +813,13 @@ public abstract class HardwareRenderer { } @Override - SurfaceTexture createSuraceTexture(HardwareLayer layer) { + SurfaceTexture createSurfaceTexture(HardwareLayer layer) { return ((GLES20TextureLayer) layer).getSurfaceTexture(); } @Override - void updateTextureLayer(HardwareLayer layer, int width, int height, - SurfaceTexture surface) { - ((GLES20TextureLayer) layer).update(width, height, surface.mSurfaceTexture); + void updateTextureLayer(HardwareLayer layer, int width, int height) { + ((GLES20TextureLayer) layer).update(width, height); } @Override diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java index 4daa892..164c657 100644 --- a/core/java/android/view/TextureView.java +++ b/core/java/android/view/TextureView.java @@ -232,7 +232,7 @@ public class TextureView extends View { protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); if (mSurface != null) { - nSetDefaultBufferSize(mSurface.mSurfaceTexture, getWidth(), getHeight()); + nSetDefaultBufferSize(mSurface, getWidth(), getHeight()); if (mListener != null) { mListener.onSurfaceTextureSizeChanged(mSurface, getWidth(), getHeight()); } @@ -247,8 +247,8 @@ public class TextureView extends View { if (mLayer == null) { mLayer = mAttachInfo.mHardwareRenderer.createHardwareLayer(); - mSurface = mAttachInfo.mHardwareRenderer.createSuraceTexture(mLayer); - nSetDefaultBufferSize(mSurface.mSurfaceTexture, getWidth(), getHeight()); + mSurface = mAttachInfo.mHardwareRenderer.createSurfaceTexture(mLayer); + nSetDefaultBufferSize(mSurface, getWidth(), getHeight()); mUpdateListener = new SurfaceTexture.OnFrameAvailableListener() { @Override @@ -290,7 +290,7 @@ public class TextureView extends View { return; } - mAttachInfo.mHardwareRenderer.updateTextureLayer(mLayer, getWidth(), getHeight(), mSurface); + mAttachInfo.mHardwareRenderer.updateTextureLayer(mLayer, getWidth(), getHeight()); invalidate(); } @@ -447,5 +447,5 @@ public class TextureView extends View { public void onSurfaceTextureDestroyed(SurfaceTexture surface); } - private static native void nSetDefaultBufferSize(int surfaceTexture, int width, int height); + private static native void nSetDefaultBufferSize(SurfaceTexture surfaceTexture, int width, int height); } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 1dfb858..888f0c0 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -17,6 +17,7 @@ package android.view; import android.util.FloatProperty; +import android.util.LocaleUtil; import android.util.Property; import com.android.internal.R; import com.android.internal.util.Predicate; @@ -6088,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 @@ -8735,6 +8740,10 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit } jumpDrawablesToCurrentState(); resolveLayoutDirection(); + if (isFocused()) { + InputMethodManager imm = InputMethodManager.peekInstance(); + imm.focusIn(this); + } } /** @@ -8772,18 +8781,8 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit * @return true if a Locale is corresponding to a RTL script. */ private static boolean isLayoutDirectionRtl(Locale locale) { - if (locale == null || locale.equals(Locale.ROOT)) return false; - // Be careful: this code will need to be changed when vertical scripts will be supported - // OR if ICU4C is updated to have the "likelySubtags" file - switch(Character.getDirectionality(locale.getDisplayName(locale).charAt(0))) { - case Character.DIRECTIONALITY_LEFT_TO_RIGHT: - return false; - case Character.DIRECTIONALITY_RIGHT_TO_LEFT: - case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC: - return true; - default: - return false; - } + return (LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE == + LocaleUtil.getLayoutDirectionFromLocale(locale)); } /** @@ -11710,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 @@ -11720,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/view/ViewAncestor.java b/core/java/android/view/ViewAncestor.java index 914973e..ba3ae58 100644 --- a/core/java/android/view/ViewAncestor.java +++ b/core/java/android/view/ViewAncestor.java @@ -4407,7 +4407,7 @@ public final class ViewAncestor extends Handler implements ViewParent, predicate.init(accessibilityId); View root = ViewAncestor.this.mView; View target = root.findViewByPredicate(predicate); - if (target != null) { + if (target != null && target.isShown()) { info = target.createAccessibilityNodeInfo(); } } finally { @@ -4439,7 +4439,7 @@ public final class ViewAncestor extends Handler implements ViewParent, try { View root = ViewAncestor.this.mView; View target = root.findViewById(viewId); - if (target != null) { + if (target != null && target.isShown()) { info = target.createAccessibilityNodeInfo(); } } finally { @@ -4486,7 +4486,7 @@ public final class ViewAncestor extends Handler implements ViewParent, root = ViewAncestor.this.mView; } - if (root == null) { + if (root == null || !root.isShown()) { return; } @@ -4501,7 +4501,9 @@ public final class ViewAncestor extends Handler implements ViewParent, final int viewCount = foundViews.size(); for (int i = 0; i < viewCount; i++) { View foundView = foundViews.get(i); - infos.add(foundView.createAccessibilityNodeInfo()); + if (foundView.isShown()) { + infos.add(foundView.createAccessibilityNodeInfo()); + } } } finally { try { @@ -4611,7 +4613,8 @@ public final class ViewAncestor extends Handler implements ViewParent, return null; } mFindByAccessibilityIdPredicate.init(accessibilityId); - return root.findViewByPredicate(mFindByAccessibilityIdPredicate); + View foundView = root.findViewByPredicate(mFindByAccessibilityIdPredicate); + return (foundView != null && foundView.isShown()) ? foundView : null; } private final class FindByAccessibilitytIdPredicate implements Predicate<View> { diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 57ee8a0..a6bce75 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -2023,10 +2023,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager @Override public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); - for (int i = 0, count = mChildrenCount; i < count; i++) { View child = mChildren[i]; - info.addChild(child); + if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) { + info.addChild(child); + } } } diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java index 9eddf23..a3de285 100644 --- a/core/java/android/view/ViewPropertyAnimator.java +++ b/core/java/android/view/ViewPropertyAnimator.java @@ -349,7 +349,7 @@ public class ViewPropertyAnimator { } } mPendingAnimations.clear(); - mView.getHandler().removeCallbacks(mAnimationStarter); + mView.removeCallbacks(mAnimationStarter); } /** @@ -705,7 +705,7 @@ public class ViewPropertyAnimator { NameValuesHolder nameValuePair = new NameValuesHolder(constantName, startValue, byValue); mPendingAnimations.add(nameValuePair); - mView.getHandler().removeCallbacks(mAnimationStarter); + mView.removeCallbacks(mAnimationStarter); mView.post(mAnimationStarter); } diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java index c361a4a..761007f 100644 --- a/core/java/android/webkit/WebSettings.java +++ b/core/java/android/webkit/WebSettings.java @@ -59,6 +59,7 @@ public class WebSettings { * NORMAL is 100% * LARGER is 150% * LARGEST is 200% + * @deprecated Use {@link WebSettings#setTextZoom(int)} and {@link WebSettings#getTextZoom()} instead. */ public enum TextSize { SMALLEST(50), @@ -158,7 +159,7 @@ public class WebSettings { // know what they are. private LayoutAlgorithm mLayoutAlgorithm = LayoutAlgorithm.NARROW_COLUMNS; private Context mContext; - private TextSize mTextSize = TextSize.NORMAL; + private int mTextSize = 100; private String mStandardFontFamily = "sans-serif"; private String mFixedFontFamily = "monospace"; private String mSansSerifFontFamily = "sans-serif"; @@ -709,26 +710,61 @@ public class WebSettings { } /** + * Set the text zoom of the page in percent. Default is 100. + * @param textZoom A percent value for increasing or decreasing the text. + */ + public synchronized void setTextZoom(int textZoom) { + if (mTextSize != textZoom) { + if (WebView.mLogEvent) { + EventLog.writeEvent(EventLogTags.BROWSER_TEXT_SIZE_CHANGE, + mTextSize, textZoom); + } + mTextSize = textZoom; + postSync(); + } + } + + /** + * Get the text zoom of the page in percent. + * @return A percent value describing the text zoom. + * @see setTextSizeZoom + */ + public synchronized int getTextZoom() { + return mTextSize; + } + + /** * Set the text size of the page. * @param t A TextSize value for increasing or decreasing the text. * @see WebSettings.TextSize + * @deprecated Use {@link #setTextZoom(int)} instead */ public synchronized void setTextSize(TextSize t) { - if (WebView.mLogEvent && mTextSize != t ) { - EventLog.writeEvent(EventLogTags.BROWSER_TEXT_SIZE_CHANGE, - mTextSize.value, t.value); - } - mTextSize = t; - postSync(); + setTextZoom(t.value); } /** - * Get the text size of the page. + * Get the text size of the page. If the text size was previously specified + * in percent using {@link #setTextZoom(int)}, this will return + * the closest matching {@link TextSize}. * @return A TextSize enum value describing the text size. * @see WebSettings.TextSize + * @deprecated Use {@link #getTextZoom()} instead */ public synchronized TextSize getTextSize() { - return mTextSize; + TextSize closestSize = null; + int smallestDelta = Integer.MAX_VALUE; + for (TextSize size : TextSize.values()) { + int delta = Math.abs(mTextSize - size.value); + if (delta == 0) { + return size; + } + if (delta < smallestDelta) { + smallestDelta = delta; + closestSize = size; + } + } + return closestSize != null ? closestSize : TextSize.NORMAL; } /** diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java index 092c2f7..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; @@ -135,11 +133,44 @@ public class GridLayout extends ViewGroup { */ public static final int UNDEFINED = Integer.MIN_VALUE; + /** + * This constant is an {@link #setAlignmentMode(int) alignmentMode}. + * When the {@code alignmentMode} is set to {@link #ALIGN_BOUNDS}, alignment + * is made between the edges of each component's raw + * view boundary: i.e. the area delimited by the component's: + * {@link android.view.View#getTop() top}, + * {@link android.view.View#getLeft() left}, + * {@link android.view.View#getBottom() bottom} and + * {@link android.view.View#getRight() right} properties. + * <p> + * For example, when {@code GridLayout} is in {@link #ALIGN_BOUNDS} mode, + * children that belong to a row group that uses {@link #TOP} alignment will + * all return the same value when their {@link android.view.View#getTop()} + * method is called. + * + * @see #setAlignmentMode(int) + */ + public static final int ALIGN_BOUNDS = 0; + + /** + * This constant is an {@link #setAlignmentMode(int) alignmentMode}. + * When the {@code alignmentMode} is set to {@link #ALIGN_MARGINS}, + * the bounds of each view are extended outwards, according + * to their margins, before the edges of the resulting rectangle are aligned. + * <p> + * For example, when {@code GridLayout} is in {@link #ALIGN_MARGINS} mode, + * the quantity {@code top - layoutParams.topMargin} is the same for all children that + * belong to a row group that uses {@link #TOP} alignment. + * + * @see #setAlignmentMode(int) + */ + public static final int ALIGN_MARGINS = 1; + // Misc constants private static final String TAG = GridLayout.class.getName(); private static final boolean DEBUG = false; - private static final Paint GRID_PAINT = new Paint(); + private static Paint GRID_PAINT; private static final double GOLDEN_RATIO = (1 + Math.sqrt(5)) / 2; private static final int MIN = 0; private static final int PRF = 1; @@ -151,7 +182,7 @@ public class GridLayout extends ViewGroup { private static final int DEFAULT_COUNT = UNDEFINED; private static final boolean DEFAULT_USE_DEFAULT_MARGINS = false; private static final boolean DEFAULT_ORDER_PRESERVED = false; - private static final boolean DEFAULT_MARGINS_INCLUDED = true; + private static final int DEFAULT_ALIGNMENT_MODE = ALIGN_MARGINS; // todo remove this private static final int DEFAULT_CONTAINER_MARGIN = 20; @@ -161,14 +192,17 @@ public class GridLayout extends ViewGroup { private static final int ROW_COUNT = styleable.GridLayout_rowCount; private static final int COLUMN_COUNT = styleable.GridLayout_columnCount; private static final int USE_DEFAULT_MARGINS = styleable.GridLayout_useDefaultMargins; - private static final int MARGINS_INCLUDED = styleable.GridLayout_marginsIncludedInAlignment; + private static final int ALIGNMENT_MODE = styleable.GridLayout_alignmentMode; private static final int ROW_ORDER_PRESERVED = styleable.GridLayout_rowOrderPreserved; private static final int COLUMN_ORDER_PRESERVED = styleable.GridLayout_columnOrderPreserved; // Static initialization static { - GRID_PAINT.setColor(Color.argb(50, 255, 255, 255)); + if (DEBUG) { + GRID_PAINT = new Paint(); + GRID_PAINT.setColor(Color.argb(50, 255, 255, 255)); + } } // Instance variables @@ -178,7 +212,7 @@ public class GridLayout extends ViewGroup { private boolean mLayoutParamsValid = false; private int mOrientation = DEFAULT_ORIENTATION; private boolean mUseDefaultMargins = DEFAULT_USE_DEFAULT_MARGINS; - private boolean mMarginsIncludedInAlignment = DEFAULT_MARGINS_INCLUDED; + private int mAlignmentMode = DEFAULT_ALIGNMENT_MODE; private int mDefaultGravity = Gravity.NO_GRAVITY; /* package */ boolean accommodateBothMinAndMax = false; @@ -189,10 +223,7 @@ public class GridLayout extends ViewGroup { * {@inheritDoc} */ public GridLayout(Context context) { - super(context); - if (DEBUG) { - setWillNotDraw(false); - } + this(context, null, 0); } /** @@ -200,6 +231,9 @@ public class GridLayout extends ViewGroup { */ public GridLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); + if (DEBUG) { + setWillNotDraw(false); + } processAttributes(context, attrs); } @@ -207,18 +241,17 @@ public class GridLayout extends ViewGroup { * {@inheritDoc} */ public GridLayout(Context context, AttributeSet attrs) { - super(context, attrs); - processAttributes(context, attrs); + this(context, attrs, 0); } private void processAttributes(Context context, AttributeSet attrs) { TypedArray a = context.obtainStyledAttributes(attrs, styleable.GridLayout); try { - setRowCount(a.getInteger(ROW_COUNT, DEFAULT_COUNT)); - setColumnCount(a.getInteger(COLUMN_COUNT, DEFAULT_COUNT)); - mOrientation = a.getInteger(ORIENTATION, DEFAULT_ORIENTATION); + setRowCount(a.getInt(ROW_COUNT, DEFAULT_COUNT)); + setColumnCount(a.getInt(COLUMN_COUNT, DEFAULT_COUNT)); + mOrientation = a.getInt(ORIENTATION, DEFAULT_ORIENTATION); mUseDefaultMargins = a.getBoolean(USE_DEFAULT_MARGINS, DEFAULT_USE_DEFAULT_MARGINS); - mMarginsIncludedInAlignment = a.getBoolean(MARGINS_INCLUDED, DEFAULT_MARGINS_INCLUDED); + mAlignmentMode = a.getInt(ALIGNMENT_MODE, DEFAULT_ALIGNMENT_MODE); setRowOrderPreserved(a.getBoolean(ROW_ORDER_PRESERVED, DEFAULT_ORDER_PRESERVED)); setColumnOrderPreserved(a.getBoolean(COLUMN_ORDER_PRESERVED, DEFAULT_ORDER_PRESERVED)); } finally { @@ -348,15 +381,15 @@ public class GridLayout extends ViewGroup { * When {@code false}, the default value of all margins is zero. * <p> * When setting to {@code true}, consider setting the value of the - * {@link #setMarginsIncludedInAlignment(boolean) marginsIncludedInAlignment} - * property to {@code false}. + * {@link #setAlignmentMode(int) alignmentMode} + * property to {@link #ALIGN_BOUNDS}. * <p> * The default value of this property is {@code false}. * * @param useDefaultMargins use {@code true} to make GridLayout allocate default margins * * @see #getUseDefaultMargins() - * @see #setMarginsIncludedInAlignment(boolean) + * @see #setAlignmentMode(int) * * @see MarginLayoutParams#leftMargin * @see MarginLayoutParams#topMargin @@ -371,36 +404,38 @@ public class GridLayout extends ViewGroup { } /** - * Returns whether GridLayout aligns the edges of the view or the edges - * of the larger rectangle created by extending the view by its associated - * margins. + * Returns the alignment mode. + * + * @return the alignment mode; either {@link #ALIGN_BOUNDS} or {@link #ALIGN_MARGINS} * - * @see #setMarginsIncludedInAlignment(boolean) + * @see #ALIGN_BOUNDS + * @see #ALIGN_MARGINS * - * @return {@code true} if alignment is between edges including margins + * @see #setAlignmentMode(int) * - * @attr ref android.R.styleable#GridLayout_marginsIncludedInAlignment + * @attr ref android.R.styleable#GridLayout_alignmentMode */ - public boolean getMarginsIncludedInAlignment() { - return mMarginsIncludedInAlignment; + public int getAlignmentMode() { + return mAlignmentMode; } /** - * When {@code true}, the bounds of a view are extended outwards according to its - * margins before the edges of the resulting rectangle are aligned. - * When {@code false}, alignment occurs between the bounds of the view - i.e. - * {@link #LEFT} alignment means align the left edges of the view. + * Sets the alignment mode to be used for all of the alignments between the + * children of this container. * <p> - * The default value of this property is {@code true}. + * The default value of this property is {@link #ALIGN_MARGINS}. + * + * @param alignmentMode either {@link #ALIGN_BOUNDS} or {@link #ALIGN_MARGINS} * - * @param marginsIncludedInAlignment {@code true} if alignment between edges includes margins + * @see #ALIGN_BOUNDS + * @see #ALIGN_MARGINS * - * @see #getMarginsIncludedInAlignment() + * @see #getAlignmentMode() * - * @attr ref android.R.styleable#GridLayout_marginsIncludedInAlignment + * @attr ref android.R.styleable#GridLayout_alignmentMode */ - public void setMarginsIncludedInAlignment(boolean marginsIncludedInAlignment) { - mMarginsIncludedInAlignment = marginsIncludedInAlignment; + public void setAlignmentMode(int alignmentMode) { + mAlignmentMode = alignmentMode; requestLayout(); } @@ -723,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); @@ -782,7 +780,7 @@ public class GridLayout extends ViewGroup { private int getMeasurementIncludingMargin(View c, boolean horizontal, int measurementType) { int result = getMeasurement(c, horizontal, measurementType); - if (mMarginsIncludedInAlignment) { + if (mAlignmentMode == ALIGN_MARGINS) { int leadingMargin = getMargin(c, true, horizontal); int trailingMargin = getMargin(c, false, horizontal); return result + leadingMargin + trailingMargin; @@ -844,8 +842,8 @@ public class GridLayout extends ViewGroup { int pWidth = getMeasurement(view, true, PRF); int pHeight = getMeasurement(view, false, PRF); - Alignment hAlignment = columnGroup.alignment; - Alignment vAlignment = rowGroup.alignment; + Alignment hAlign = columnGroup.alignment; + Alignment vAlign = rowGroup.alignment; int dx, dy; @@ -853,22 +851,23 @@ public class GridLayout extends ViewGroup { Bounds rowBounds = mVerticalAxis.getGroupBounds().getValue(i); // Gravity offsets: the location of the alignment group relative to its cell group. - int c2ax = protect(hAlignment.getAlignmentValue(null, cellWidth - colBounds.size())); - int c2ay = protect(vAlignment.getAlignmentValue(null, cellHeight - rowBounds.size())); + int type = PRF; + int c2ax = protect(hAlign.getAlignmentValue(null, cellWidth - colBounds.size(), type)); + int c2ay = protect(vAlign.getAlignmentValue(null, cellHeight - rowBounds.size(), type)); - if (mMarginsIncludedInAlignment) { + if (mAlignmentMode == ALIGN_MARGINS) { int leftMargin = getMargin(view, true, true); int topMargin = getMargin(view, true, false); int rightMargin = getMargin(view, false, true); int bottomMargin = getMargin(view, false, false); // Same calculation as getMeasurementIncludingMargin() - int measuredWidth = leftMargin + pWidth + rightMargin; - int measuredHeight = topMargin + pHeight + bottomMargin; + int mWidth = leftMargin + pWidth + rightMargin; + int mHeight = topMargin + pHeight + bottomMargin; // Alignment offsets: the location of the view relative to its alignment group. - int a2vx = colBounds.before - hAlignment.getAlignmentValue(view, measuredWidth); - int a2vy = rowBounds.before - vAlignment.getAlignmentValue(view, measuredHeight); + int a2vx = colBounds.before - hAlign.getAlignmentValue(view, mWidth, type); + int a2vy = rowBounds.before - vAlign.getAlignmentValue(view, mHeight, type); dx = c2ax + a2vx + leftMargin; dy = c2ay + a2vy + topMargin; @@ -877,15 +876,15 @@ public class GridLayout extends ViewGroup { cellHeight -= topMargin + bottomMargin; } else { // Alignment offsets: the location of the view relative to its alignment group. - int a2vx = colBounds.before - hAlignment.getAlignmentValue(view, pWidth); - int a2vy = rowBounds.before - vAlignment.getAlignmentValue(view, pHeight); + int a2vx = colBounds.before - hAlign.getAlignmentValue(view, pWidth, type); + int a2vy = rowBounds.before - vAlign.getAlignmentValue(view, pHeight, type); dx = c2ax + a2vx; dy = c2ay + a2vy; } - int width = hAlignment.getSizeInCell(view, pWidth, cellWidth); - int height = vAlignment.getSizeInCell(view, pHeight, cellHeight); + int width = hAlign.getSizeInCell(view, pWidth, cellWidth, type); + int height = vAlign.getSizeInCell(view, pHeight, cellHeight, type); int cx = paddingLeft + x1 + dx; int cy = paddingTop + y1 + dy; @@ -1003,7 +1002,7 @@ public class GridLayout extends ViewGroup { int size = getMeasurementIncludingMargin(c, horizontal, PRF); // todo test this works correctly when the returned value is UNDEFINED - int before = g.alignment.getAlignmentValue(c, size); + int before = g.alignment.getAlignmentValue(c, size, PRF); bounds.include(before, size - before); } } @@ -1107,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>(); @@ -1358,7 +1354,7 @@ public class GridLayout extends ViewGroup { private int getLocationIncludingMargin(View view, boolean leading, int index) { int location = locations[index]; int margin; - if (!mMarginsIncludedInAlignment) { + if (mAlignmentMode != ALIGN_MARGINS) { margin = (leading ? leadingMargins : trailingMargins)[index]; } else { margin = 0; @@ -1370,7 +1366,7 @@ public class GridLayout extends ViewGroup { Arrays.fill(a, MIN_VALUE); a[0] = 0; solve(getArcs(), a); - if (!mMarginsIncludedInAlignment) { + if (mAlignmentMode != ALIGN_MARGINS) { addMargins(); } } @@ -1459,6 +1455,7 @@ public class GridLayout extends ViewGroup { spanSizes = null; leadingMargins = null; trailingMargins = null; + arcs = null; minima = null; weights = null; locations = null; @@ -1750,16 +1747,16 @@ public class GridLayout extends ViewGroup { private void init(Context context, AttributeSet attrs, int defaultGravity) { TypedArray a = context.obtainStyledAttributes(attrs, styleable.GridLayout_Layout); try { - int gravity = a.getInteger(GRAVITY, defaultGravity); + int gravity = a.getInt(GRAVITY, defaultGravity); - int column = a.getInteger(COLUMN, DEFAULT_COLUMN); - int columnSpan = a.getInteger(COLUMN_SPAN, DEFAULT_SPAN_SIZE); + int column = a.getInt(COLUMN, DEFAULT_COLUMN); + int columnSpan = a.getInt(COLUMN_SPAN, DEFAULT_SPAN_SIZE); Interval hSpan = new Interval(column, column + columnSpan); this.columnGroup = new Group(hSpan, getColumnAlignment(gravity, width)); this.columnWeight = a.getFloat(COLUMN_WEIGHT, getDefaultWeight(width)); - int row = a.getInteger(ROW, DEFAULT_ROW); - int rowSpan = a.getInteger(ROW_SPAN, DEFAULT_SPAN_SIZE); + int row = a.getInt(ROW, DEFAULT_ROW); + int rowSpan = a.getInt(ROW_SPAN, DEFAULT_SPAN_SIZE); Interval vSpan = new Interval(row, row + rowSpan); this.rowGroup = new Group(vSpan, getRowAlignment(gravity, height)); this.rowWeight = a.getFloat(ROW_WEIGHT, getDefaultWeight(height)); @@ -2156,57 +2153,63 @@ public class GridLayout extends ViewGroup { * {@link Group#alignment alignment}. Overall placement of the view in the cell * group is specified by the two alignments which act along each axis independently. * <p> - * An Alignment implementation must define the {@link #getAlignmentValue(View, int)} + * An Alignment implementation must define {@link #getAlignmentValue(View, int, int)}, * to return the appropriate value for the type of alignment being defined. * The enclosing algorithms position the children - * so that the values returned from the alignment + * so that the locations defined by the alignment values * are the same for all of the views in a group. * <p> * The GridLayout class defines the most common alignments used in general layout: * {@link #TOP}, {@link #LEFT}, {@link #BOTTOM}, {@link #RIGHT}, {@link #CENTER}, {@link * #BASELINE} and {@link #FILL}. */ - public static interface Alignment { + public static abstract class Alignment { /** * Returns an alignment value. In the case of vertical alignments the value * returned should indicate the distance from the top of the view to the * alignment location. * For horizontal alignments measurement is made from the left edge of the component. * - * @param view the view to which this alignment should be applied - * @param viewSize the measured size of the view - * @return the alignment value + * @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. This feature + * is currently unused as GridLayout only supports one + * type of measurement: {@link View#measure(int, int)}. + * + * @return the alignment value */ - public int getAlignmentValue(View view, int viewSize); + public abstract int getAlignmentValue(View view, int viewSize, int measurementType); /** * Returns the size of the view specified by this alignment. * In the case of vertical alignments this method should return a height; for * horizontal alignments this method should return the width. + * <p> + * The default implementation returns {@code viewSize}. * - * @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 - * @return the aligned size + * @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. This feature + * is currently unused as GridLayout only supports one + * type of measurement: {@link View#measure(int, int)}. + * + * @return the aligned size */ - public int getSizeInCell(View view, int viewSize, int cellSize); - } - - private static abstract class AbstractAlignment implements Alignment { - public int getSizeInCell(View view, int viewSize, int cellSize) { + public int getSizeInCell(View view, int viewSize, int cellSize, int measurementType) { return viewSize; } } - private static final Alignment LEADING = new AbstractAlignment() { - public int getAlignmentValue(View view, int viewSize) { + private static final Alignment LEADING = new Alignment() { + public int getAlignmentValue(View view, int viewSize, int measurementType) { return 0; } }; - private static final Alignment TRAILING = new AbstractAlignment() { - public int getAlignmentValue(View view, int viewSize) { + private static final Alignment TRAILING = new Alignment() { + public int getAlignmentValue(View view, int viewSize, int measurementType) { return viewSize; } }; @@ -2240,8 +2243,8 @@ public class GridLayout extends ViewGroup { * This constant may be used in both {@link LayoutParams#rowGroup rowGroups} and {@link * LayoutParams#columnGroup columnGroups}. */ - public static final Alignment CENTER = new AbstractAlignment() { - public int getAlignmentValue(View view, int viewSize) { + public static final Alignment CENTER = new Alignment() { + public int getAlignmentValue(View view, int viewSize, int measurementType) { return viewSize >> 1; } }; @@ -2253,8 +2256,8 @@ public class GridLayout extends ViewGroup { * * @see View#getBaseline() */ - public static final Alignment BASELINE = new AbstractAlignment() { - public int getAlignmentValue(View view, int height) { + public static final Alignment BASELINE = new Alignment() { + public int getAlignmentValue(View view, int viewSize, int measurementType) { if (view == null) { return UNDEFINED; } @@ -2274,12 +2277,13 @@ public class GridLayout extends ViewGroup { * {@link LayoutParams#columnGroup columnGroups}. */ public static final Alignment FILL = new Alignment() { - public int getAlignmentValue(View view, int viewSize) { + public int getAlignmentValue(View view, int viewSize, int measurementType) { return UNDEFINED; } - public int getSizeInCell(View view, int viewSize, int cellSize) { + @Override + public int getSizeInCell(View view, int viewSize, int cellSize, int measurementType) { return cellSize; } }; -}
\ No newline at end of file +} 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/app/AlertController.java b/core/java/com/android/internal/app/AlertController.java index 71a7a52..8d6caa1 100644 --- a/core/java/com/android/internal/app/AlertController.java +++ b/core/java/com/android/internal/app/AlertController.java @@ -575,9 +575,13 @@ public class AlertController { params.weight = 0.5f; button.setLayoutParams(params); View leftSpacer = mWindow.findViewById(R.id.leftSpacer); - leftSpacer.setVisibility(View.VISIBLE); + if (leftSpacer != null) { + leftSpacer.setVisibility(View.VISIBLE); + } View rightSpacer = mWindow.findViewById(R.id.rightSpacer); - rightSpacer.setVisibility(View.VISIBLE); + if (rightSpacer != null) { + rightSpacer.setVisibility(View.VISIBLE); + } } private void setBackground(LinearLayout topPanel, LinearLayout contentPanel, diff --git a/core/java/com/android/internal/net/VpnConfig.aidl b/core/java/com/android/internal/net/VpnConfig.aidl new file mode 100644 index 0000000..be1684c --- /dev/null +++ b/core/java/com/android/internal/net/VpnConfig.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2011 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.net; + +parcelable VpnConfig; diff --git a/core/java/com/android/internal/net/VpnConfig.java b/core/java/com/android/internal/net/VpnConfig.java new file mode 100644 index 0000000..773be5b --- /dev/null +++ b/core/java/com/android/internal/net/VpnConfig.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2011 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.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, + * and com.android.server.connectivity.Vpn. Internal use only. + * + * @hide + */ +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; + public String configureActivity; + public int mtu = -1; + public String addresses; + public String routes; + public String dnsServers; + public long startTime = -1; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeString(packageName); + out.writeString(sessionName); + out.writeString(interfaceName); + out.writeString(configureActivity); + out.writeInt(mtu); + out.writeString(addresses); + out.writeString(routes); + out.writeString(dnsServers); + out.writeLong(startTime); + } + + public static final Parcelable.Creator<VpnConfig> CREATOR = + new Parcelable.Creator<VpnConfig>() { + @Override + public VpnConfig createFromParcel(Parcel in) { + VpnConfig config = new VpnConfig(); + config.packageName = in.readString(); + config.sessionName = in.readString(); + config.interfaceName = in.readString(); + config.configureActivity = in.readString(); + config.mtu = in.readInt(); + config.addresses = in.readString(); + config.routes = in.readString(); + config.dnsServers = in.readString(); + config.startTime = in.readLong(); + return config; + } + + @Override + public VpnConfig[] newArray(int size) { + return new VpnConfig[size]; + } + }; +} diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl index 2ff0413..c11fc10 100644 --- a/core/java/com/android/internal/statusbar/IStatusBar.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl @@ -35,5 +35,6 @@ oneway interface IStatusBar void setImeWindowStatus(in IBinder token, int vis, int backDisposition); void setHardKeyboardStatus(boolean available, boolean enabled); void userActivity(); + void toggleRecentApps(); } diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl index 3f2b1ef..a9e5057 100644 --- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl @@ -47,4 +47,5 @@ interface IStatusBarService void setSystemUiVisibility(int vis); void setHardKeyboardEnabled(boolean enabled); void userActivity(); + void toggleRecentApps(); } 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/java/com/android/internal/widget/DialogTitle.java b/core/java/com/android/internal/widget/DialogTitle.java index 125d2c5..cd165dc 100644 --- a/core/java/com/android/internal/widget/DialogTitle.java +++ b/core/java/com/android/internal/widget/DialogTitle.java @@ -54,15 +54,19 @@ public class DialogTitle extends TextView { if (ellipsisCount > 0) { setSingleLine(false); - TypedArray a = mContext.obtainStyledAttributes( - android.R.style.TextAppearance_Medium, - android.R.styleable.TextAppearance); + TypedArray a = mContext.obtainStyledAttributes(null, + android.R.styleable.TextAppearance, + android.R.attr.textAppearanceMedium, + android.R.style.TextAppearance_Medium); final int textSize = a.getDimensionPixelSize( android.R.styleable.TextAppearance_textSize, (int) (20 * getResources().getDisplayMetrics().density)); + final int textColor = a.getColor( + android.R.styleable.TextAppearance_textColor, 0xffffffff); // textSize is already expressed in pixels setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize); + setTextColor(textColor); setMaxLines(2); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index 7e82efb..e301e44 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -22,6 +22,7 @@ #include "GraphicsJNI.h" #include <nativehelper/JNIHelp.h> #include <android_runtime/AndroidRuntime.h> +#include <android_runtime/android_graphics_SurfaceTexture.h> #include <utils/ResourceTypes.h> #include <gui/SurfaceTexture.h> @@ -644,11 +645,13 @@ static void android_view_GLES20Canvas_resizeLayer(JNIEnv* env, jobject clazz, } static void android_view_GLES20Canvas_updateTextureLayer(JNIEnv* env, jobject clazz, - Layer* layer, jint width, jint height, SurfaceTexture* surface) { + Layer* layer, jint width, jint height, jobject surface) { float transform[16]; - surface->updateTexImage(); - surface->getTransformMatrix(transform); - GLenum renderTarget = surface->getCurrentTextureTarget(); + sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, surface)); + + surfaceTexture->updateTexImage(); + surfaceTexture->getTransformMatrix(transform); + GLenum renderTarget = surfaceTexture->getCurrentTextureTarget(); LayerRenderer::updateTextureLayer(layer, width, height, renderTarget, transform); } @@ -793,7 +796,8 @@ static JNINativeMethod gMethods[] = { { "nCreateLayer", "(IIZ[I)I", (void*) android_view_GLES20Canvas_createLayer }, { "nResizeLayer", "(III[I)V" , (void*) android_view_GLES20Canvas_resizeLayer }, { "nCreateTextureLayer", "([I)I", (void*) android_view_GLES20Canvas_createTextureLayer }, - { "nUpdateTextureLayer", "(IIII)V", (void*) android_view_GLES20Canvas_updateTextureLayer }, + { "nUpdateTextureLayer", "(IIILandroid/graphics/SurfaceTexture;)V", + (void*) android_view_GLES20Canvas_updateTextureLayer }, { "nDestroyLayer", "(I)V", (void*) android_view_GLES20Canvas_destroyLayer }, { "nDestroyLayerDeferred", "(I)V", (void*) android_view_GLES20Canvas_destroyLayerDeferred }, { "nDrawLayer", "(IIFFI)V", (void*) android_view_GLES20Canvas_drawLayer }, diff --git a/core/jni/android_view_TextureView.cpp b/core/jni/android_view_TextureView.cpp index c5d86c8..b046b23 100644 --- a/core/jni/android_view_TextureView.cpp +++ b/core/jni/android_view_TextureView.cpp @@ -17,6 +17,7 @@ #include "jni.h" #include <nativehelper/JNIHelp.h> #include <android_runtime/AndroidRuntime.h> +#include <android_runtime/android_graphics_SurfaceTexture.h> #include <gui/SurfaceTexture.h> @@ -27,10 +28,10 @@ namespace android { // ---------------------------------------------------------------------------- static void android_view_TextureView_setDefaultBufferSize(JNIEnv* env, jobject, - jint surfaceTexture, jint width, jint height) { + jobject surface, jint width, jint height) { - sp<SurfaceTexture> surface = reinterpret_cast<SurfaceTexture*>(surfaceTexture); - surface->setDefaultBufferSize(width, height); + sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, surface)); + surfaceTexture->setDefaultBufferSize(width, height); } // ---------------------------------------------------------------------------- @@ -40,7 +41,8 @@ static void android_view_TextureView_setDefaultBufferSize(JNIEnv* env, jobject, const char* const kClassPathName = "android/view/TextureView"; static JNINativeMethod gMethods[] = { - { "nSetDefaultBufferSize", "(III)V", (void*) android_view_TextureView_setDefaultBufferSize } + { "nSetDefaultBufferSize", "(Landroid/graphics/SurfaceTexture;II)V", + (void*) android_view_TextureView_setDefaultBufferSize } }; int register_android_view_TextureView(JNIEnv* env) { diff --git a/core/jni/com_google_android_gles_jni_EGLImpl.cpp b/core/jni/com_google_android_gles_jni_EGLImpl.cpp index f777527..02974f9 100644 --- a/core/jni/com_google_android_gles_jni_EGLImpl.cpp +++ b/core/jni/com_google_android_gles_jni_EGLImpl.cpp @@ -18,6 +18,7 @@ #include "JNIHelp.h" #include <android_runtime/AndroidRuntime.h> #include <android_runtime/android_view_Surface.h> +#include <android_runtime/android_graphics_SurfaceTexture.h> #include <utils/misc.h> #include <EGL/egl.h> @@ -323,7 +324,7 @@ not_valid_surface: } static jint jni_eglCreateWindowSurfaceTexture(JNIEnv *_env, jobject _this, jobject display, - jobject config, jint native_window, jintArray attrib_list) { + jobject config, jobject native_window, jintArray attrib_list) { if (display == NULL || config == NULL || !validAttribList(_env, attrib_list)) { jniThrowException(_env, "java/lang/IllegalArgumentException", NULL); @@ -339,7 +340,7 @@ not_valid_surface: return 0; } - sp<SurfaceTexture> surfaceTexture = reinterpret_cast<SurfaceTexture*>(native_window); + sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(_env, native_window)); window = new SurfaceTextureClient(surfaceTexture); if (window == NULL) @@ -540,7 +541,7 @@ static JNINativeMethod methods[] = { {"_eglCreatePbufferSurface","(" DISPLAY CONFIG "[I)I", (void*)jni_eglCreatePbufferSurface }, {"_eglCreatePixmapSurface", "(" SURFACE DISPLAY CONFIG OBJECT "[I)V", (void*)jni_eglCreatePixmapSurface }, {"_eglCreateWindowSurface", "(" DISPLAY CONFIG OBJECT "[I)I", (void*)jni_eglCreateWindowSurface }, -{"_eglCreateWindowSurfaceTexture", "(" DISPLAY CONFIG "I[I)I", (void*)jni_eglCreateWindowSurfaceTexture }, +{"_eglCreateWindowSurfaceTexture", "(" DISPLAY CONFIG OBJECT "[I)I", (void*)jni_eglCreateWindowSurfaceTexture }, {"eglDestroyContext", "(" DISPLAY CONTEXT ")Z", (void*)jni_eglDestroyContext }, {"eglDestroySurface", "(" DISPLAY SURFACE ")Z", (void*)jni_eglDestroySurface }, {"eglMakeCurrent", "(" DISPLAY SURFACE SURFACE CONTEXT")Z", (void*)jni_eglMakeCurrent }, 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/drawable-hdpi/dialog_bottom_holo_dark.9.png b/core/res/res/drawable-hdpi/dialog_bottom_holo_dark.9.png Binary files differindex 32c2c97..5225a81 100644 --- a/core/res/res/drawable-hdpi/dialog_bottom_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/dialog_bottom_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/dialog_bottom_holo_light.9.png b/core/res/res/drawable-hdpi/dialog_bottom_holo_light.9.png Binary files differindex f1cba06..2e7e973 100644 --- a/core/res/res/drawable-hdpi/dialog_bottom_holo_light.9.png +++ b/core/res/res/drawable-hdpi/dialog_bottom_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/dialog_full_holo_dark.9.png b/core/res/res/drawable-hdpi/dialog_full_holo_dark.9.png Binary files differindex 08b163a..4591627 100644 --- a/core/res/res/drawable-hdpi/dialog_full_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/dialog_full_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/dialog_full_holo_light.9.png b/core/res/res/drawable-hdpi/dialog_full_holo_light.9.png Binary files differindex 77ec017..9cf1826 100644 --- a/core/res/res/drawable-hdpi/dialog_full_holo_light.9.png +++ b/core/res/res/drawable-hdpi/dialog_full_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/dialog_middle_holo_dark.9.png b/core/res/res/drawable-hdpi/dialog_middle_holo_dark.9.png Binary files differindex 029f186..a47ef40 100644 --- a/core/res/res/drawable-hdpi/dialog_middle_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/dialog_middle_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/dialog_middle_holo_light.9.png b/core/res/res/drawable-hdpi/dialog_middle_holo_light.9.png Binary files differindex ee1054e..9b50c73 100644 --- a/core/res/res/drawable-hdpi/dialog_middle_holo_light.9.png +++ b/core/res/res/drawable-hdpi/dialog_middle_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/dialog_top_holo_dark.9.png b/core/res/res/drawable-hdpi/dialog_top_holo_dark.9.png Binary files differindex acbd7cf..a0d36de 100644 --- a/core/res/res/drawable-hdpi/dialog_top_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/dialog_top_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/dialog_top_holo_light.9.png b/core/res/res/drawable-hdpi/dialog_top_holo_light.9.png Binary files differindex b7ddbb4..805b956 100644 --- a/core/res/res/drawable-hdpi/dialog_top_holo_light.9.png +++ b/core/res/res/drawable-hdpi/dialog_top_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/dialog_bottom_holo_dark.9.png b/core/res/res/drawable-mdpi/dialog_bottom_holo_dark.9.png Binary files differindex cc66804..a0bd4e3 100644 --- a/core/res/res/drawable-mdpi/dialog_bottom_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/dialog_bottom_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/dialog_bottom_holo_light.9.png b/core/res/res/drawable-mdpi/dialog_bottom_holo_light.9.png Binary files differindex bc734c8..12abcd2 100644 --- a/core/res/res/drawable-mdpi/dialog_bottom_holo_light.9.png +++ b/core/res/res/drawable-mdpi/dialog_bottom_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/dialog_full_holo_dark.9.png b/core/res/res/drawable-mdpi/dialog_full_holo_dark.9.png Binary files differindex 8603e93..adb8104 100644 --- a/core/res/res/drawable-mdpi/dialog_full_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/dialog_full_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/dialog_full_holo_light.9.png b/core/res/res/drawable-mdpi/dialog_full_holo_light.9.png Binary files differindex 65a318c..d7c6bbf 100644 --- a/core/res/res/drawable-mdpi/dialog_full_holo_light.9.png +++ b/core/res/res/drawable-mdpi/dialog_full_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/dialog_middle_holo_dark.9.png b/core/res/res/drawable-mdpi/dialog_middle_holo_dark.9.png Binary files differindex e39a472..42cfc52 100644 --- a/core/res/res/drawable-mdpi/dialog_middle_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/dialog_middle_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/dialog_middle_holo_light.9.png b/core/res/res/drawable-mdpi/dialog_middle_holo_light.9.png Binary files differindex ec06c17..9a08e15 100644 --- a/core/res/res/drawable-mdpi/dialog_middle_holo_light.9.png +++ b/core/res/res/drawable-mdpi/dialog_middle_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/dialog_top_holo_dark.9.png b/core/res/res/drawable-mdpi/dialog_top_holo_dark.9.png Binary files differindex 32c49f2..5d86b2a 100644 --- a/core/res/res/drawable-mdpi/dialog_top_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/dialog_top_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/dialog_top_holo_light.9.png b/core/res/res/drawable-mdpi/dialog_top_holo_light.9.png Binary files differindex 7a2bf8d..ad22f5b 100644 --- a/core/res/res/drawable-mdpi/dialog_top_holo_light.9.png +++ b/core/res/res/drawable-mdpi/dialog_top_holo_light.9.png diff --git a/core/res/res/layout/alert_dialog_holo.xml b/core/res/res/layout/alert_dialog_holo.xml index 8ee91ca..1a3573e 100644 --- a/core/res/res/layout/alert_dialog_holo.xml +++ b/core/res/res/layout/alert_dialog_holo.xml @@ -32,12 +32,10 @@ android:orientation="vertical"> <ImageView android:id="@+id/titleDividerTop" android:layout_width="match_parent" - android:layout_height="4dip" + android:layout_height="1dip" android:visibility="gone" android:scaleType="fitXY" android:gravity="fill_horizontal" - android:paddingLeft="16dip" - android:paddingRight="16dip" android:src="@android:drawable/divider_strong_holo" /> <LinearLayout android:id="@+id/title_template" android:layout_width="match_parent" @@ -45,15 +43,16 @@ android:orientation="horizontal" android:gravity="center_vertical|left" android:minHeight="@dimen/alert_dialog_title_height" - android:layout_marginLeft="32dip" - android:layout_marginRight="32dip"> + android:layout_marginLeft="16dip" + android:layout_marginRight="16dip"> <ImageView android:id="@+id/icon" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:paddingRight="16dip" + android:paddingRight="8dip" android:src="@null" /> <com.android.internal.widget.DialogTitle android:id="@+id/alertTitle" - style="?android:attr/textAppearanceMedium" + style="?android:attr/textAppearanceLarge" + android:textColor="@android:color/holo_blue" android:singleLine="true" android:ellipsize="end" android:layout_width="match_parent" @@ -61,12 +60,10 @@ </LinearLayout> <ImageView android:id="@+id/titleDivider" android:layout_width="match_parent" - android:layout_height="4dip" + android:layout_height="1dip" android:visibility="gone" android:scaleType="fitXY" android:gravity="fill_horizontal" - android:paddingLeft="16dip" - android:paddingRight="16dip" android:src="@android:drawable/divider_strong_holo" /> <!-- If the client uses a customTitle, it will be added here. --> </LinearLayout> @@ -79,10 +76,6 @@ <ScrollView android:id="@+id/scrollView" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginLeft="16dip" - android:layout_marginRight="16dip" - android:paddingTop="32dip" - android:paddingBottom="32dip" android:clipToPadding="false"> <TextView android:id="@+id/message" style="?android:attr/textAppearanceMedium" @@ -99,11 +92,7 @@ android:layout_weight="1"> <FrameLayout android:id="@+android:id/custom" android:layout_width="match_parent" - android:layout_height="wrap_content" - android:paddingTop="8dip" - android:paddingBottom="8dip" - android:paddingLeft="32dip" - android:paddingRight="32dip" /> + android:layout_height="wrap_content" /> </FrameLayout> <LinearLayout android:id="@+id/buttonPanel" @@ -113,27 +102,21 @@ android:orientation="vertical" android:divider="?android:attr/dividerHorizontal" android:showDividers="beginning" - android:dividerPadding="16dip"> + android:dividerPadding="0dip"> <LinearLayout style="?android:attr/buttonBarStyle" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" - android:paddingLeft="2dip" - android:paddingRight="2dip" + android:layoutDirection="locale" android:measureWithLargestChild="true"> - <LinearLayout android:id="@+id/leftSpacer" - android:layout_weight="0.25" - android:layout_width="0dip" - android:layout_height="wrap_content" - android:orientation="horizontal" - android:visibility="gone" /> - <Button android:id="@+id/button1" + <Button android:id="@+id/button2" android:layout_width="0dip" android:layout_gravity="left" android:layout_weight="1" android:maxLines="2" style="?android:attr/buttonBarButtonStyle" + android:textSize="14sp" android:minHeight="@dimen/alert_dialog_button_bar_height" android:layout_height="wrap_content" /> <Button android:id="@+id/button3" @@ -142,22 +125,18 @@ android:layout_weight="1" android:maxLines="2" style="?android:attr/buttonBarButtonStyle" + android:textSize="14sp" android:minHeight="@dimen/alert_dialog_button_bar_height" android:layout_height="wrap_content" /> - <Button android:id="@+id/button2" + <Button android:id="@+id/button1" android:layout_width="0dip" android:layout_gravity="right" android:layout_weight="1" android:maxLines="2" android:minHeight="@dimen/alert_dialog_button_bar_height" style="?android:attr/buttonBarButtonStyle" + android:textSize="14sp" android:layout_height="wrap_content" /> - <LinearLayout android:id="@+id/rightSpacer" - android:layout_width="0dip" - android:layout_weight="0.25" - android:layout_height="wrap_content" - android:orientation="horizontal" - android:visibility="gone" /> </LinearLayout> </LinearLayout> </LinearLayout> diff --git a/core/res/res/layout/dialog_custom_title_holo.xml b/core/res/res/layout/dialog_custom_title_holo.xml index 74b6070..5261553 100644 --- a/core/res/res/layout/dialog_custom_title_holo.xml +++ b/core/res/res/layout/dialog_custom_title_holo.xml @@ -23,18 +23,16 @@ This is an custom layout for a dialog. android:fitsSystemWindows="true"> <FrameLayout android:id="@android:id/title_container" android:layout_width="match_parent" - android:layout_height="60dip" + android:layout_height="@dimen/alert_dialog_title_height" android:layout_weight="0" android:gravity="center_vertical|left" style="?android:attr/windowTitleBackgroundStyle"> </FrameLayout> <ImageView android:id="@+id/titleDivider" android:layout_width="match_parent" - android:layout_height="4dip" + android:layout_height="1dip" android:scaleType="fitXY" android:gravity="fill_horizontal" - android:paddingLeft="16dip" - android:paddingRight="16dip" android:src="@android:drawable/divider_strong_holo" /> <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content" diff --git a/core/res/res/layout/dialog_title_holo.xml b/core/res/res/layout/dialog_title_holo.xml index 534dd8d..400ef60 100644 --- a/core/res/res/layout/dialog_title_holo.xml +++ b/core/res/res/layout/dialog_title_holo.xml @@ -26,17 +26,15 @@ enabled. <TextView android:id="@android:id/title" style="?android:attr/windowTitleStyle" android:layout_width="match_parent" android:layout_height="wrap_content" - android:minHeight="60dip" - android:paddingLeft="32dip" - android:paddingRight="32dip" + android:minHeight="@android:dimen/alert_dialog_title_height" + android:paddingLeft="16dip" + android:paddingRight="16dip" android:gravity="center_vertical|left" /> <ImageView android:id="@+id/titleDivider" android:layout_width="match_parent" - android:layout_height="4dip" + android:layout_height="1dip" android:scaleType="fitXY" android:gravity="fill_horizontal" - android:paddingLeft="16dip" - android:paddingRight="16dip" android:src="@android:drawable/divider_strong_holo" /> <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content" diff --git a/core/res/res/layout/dialog_title_icons_holo.xml b/core/res/res/layout/dialog_title_icons_holo.xml index a3cd3af..f780ab0 100644 --- a/core/res/res/layout/dialog_title_icons_holo.xml +++ b/core/res/res/layout/dialog_title_icons_holo.xml @@ -28,16 +28,16 @@ enabled. android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="center_vertical" - android:minHeight="60dip" - android:paddingLeft="32dip" - android:paddingRight="32dip"> + android:minHeight="@android:dimen/alert_dialog_title_height" + android:paddingLeft="16dip" + android:paddingRight="16dip"> <ImageView android:id="@+id/left_icon" android:layout_width="32dip" android:layout_height="32dip" android:scaleType="fitCenter" android:layout_marginRight="8dip" /> <TextView android:id="@android:id/title" - style="?android:attr/windowTitleStyle" + style="?android:attr/windowTitleStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="0" /> @@ -50,11 +50,9 @@ enabled. <ImageView android:id="@+id/titleDivider" android:layout_width="match_parent" - android:layout_height="4dip" + android:layout_height="1dip" android:scaleType="fitXY" android:gravity="fill_horizontal" - android:paddingLeft="16dip" - android:paddingRight="16dip" android:src="@android:drawable/divider_strong_holo" /> <FrameLayout diff --git a/core/res/res/layout/preference_widget_seekbar.xml b/core/res/res/layout/preference_widget_seekbar.xml new file mode 100644 index 0000000..e4cf86d --- /dev/null +++ b/core/res/res/layout/preference_widget_seekbar.xml @@ -0,0 +1,87 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2011 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. +--> + +<!-- Layout for a Preference in a PreferenceActivity. The + Preference is able to place a specific widget for its particular + type in the "widget_frame" layout. --> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:minHeight="?android:attr/listPreferredItemHeight" + android:gravity="center_vertical" + android:paddingRight="?android:attr/scrollbarSize"> + + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:gravity="center" + android:minWidth="@dimen/preference_icon_minWidth" + android:orientation="horizontal"> + <ImageView + android:id="@+android:id/icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:minWidth="48dp" + /> + </LinearLayout> + + <RelativeLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginLeft="16dip" + android:layout_marginRight="8dip" + android:layout_marginTop="6dip" + android:layout_marginBottom="6dip" + android:layout_weight="1"> + + <TextView android:id="@+android:id/title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:singleLine="true" + android:textAppearance="?android:attr/textAppearanceMedium" + android:ellipsize="marquee" + android:fadingEdge="horizontal" /> + + <TextView android:id="@+android:id/summary" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_below="@android:id/title" + android:layout_alignLeft="@android:id/title" + android:textAppearance="?android:attr/textAppearanceSmall" + android:textColor="?android:attr/textColorSecondary" + android:maxLines="4" /> + + <!-- Preference should place its actual preference widget here. --> + <LinearLayout android:id="@+android:id/widget_frame" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_below="@android:id/summary" + android:layout_alignLeft="@android:id/title" + android:minWidth="@dimen/preference_widget_width" + android:gravity="center" + android:orientation="vertical" /> + + <SeekBar android:id="@+android:id/seekbar" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_below="@android:id/summary" + android:layout_toRightOf="@android:id/widget_frame" + android:layout_alignParentRight="true" /> + + </RelativeLayout> + +</LinearLayout> diff --git a/core/res/res/layout/select_dialog_holo.xml b/core/res/res/layout/select_dialog_holo.xml index 7c95693..06a5d96 100644 --- a/core/res/res/layout/select_dialog_holo.xml +++ b/core/res/res/layout/select_dialog_holo.xml @@ -27,9 +27,6 @@ android:id="@+android:id/select_dialog_listview" android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_marginTop="5dip" - android:paddingLeft="16dip" - android:paddingRight="16dip" android:cacheColorHint="@null" android:divider="?android:attr/listDividerAlertDialog" android:scrollbars="vertical" 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/layout/status_bar_latest_event_content.xml b/core/res/res/layout/status_bar_latest_event_content.xml index 676c38b..0dc6741 100644 --- a/core/res/res/layout/status_bar_latest_event_content.xml +++ b/core/res/res/layout/status_bar_latest_event_content.xml @@ -1,4 +1,5 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/status_bar_latest_event_content" android:layout_width="match_parent" android:layout_height="match_parent" > @@ -8,41 +9,9 @@ android:background="@drawable/notify_panel_notification_icon_bg" android:scaleType="center" /> - <LinearLayout - android:layout_width="0dp" + <include layout="@layout/status_bar_latest_event_content_large_icon" + android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_gravity="center_vertical" - android:layout_weight="1" - android:orientation="vertical" - android:paddingLeft="16dp" - > - <TextView android:id="@+id/title" - android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:singleLine="true" - android:ellipsize="marquee" - android:fadingEdge="horizontal" - android:layout_marginBottom="-3dp" - /> - <TextView android:id="@+id/text" - android:textAppearance="@style/TextAppearance.StatusBar.EventContent" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_weight="1" - android:layout_marginTop="-2dp" - android:singleLine="true" - android:ellipsize="marquee" - android:fadingEdge="horizontal" - /> - </LinearLayout> - <TextView android:id="@+id/info" - android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:singleLine="true" - android:gravity="center_vertical" - android:paddingLeft="8dp" + android:layout_gravity="center" /> </LinearLayout> - diff --git a/core/res/res/layout/status_bar_latest_event_content_large_icon.xml b/core/res/res/layout/status_bar_latest_event_content_large_icon.xml index ebdaaa3..d937392 100644 --- a/core/res/res/layout/status_bar_latest_event_content_large_icon.xml +++ b/core/res/res/layout/status_bar_latest_event_content_large_icon.xml @@ -1,50 +1,65 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/status_bar_latest_event_content_large_icon" android:layout_width="match_parent" - android:layout_height="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:orientation="vertical" + android:paddingLeft="8dp" + android:paddingRight="8dp" > + <TextView android:id="@+id/title" + android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:singleLine="true" + android:ellipsize="marquee" + android:fadingEdge="horizontal" + /> + <TextView android:id="@+id/text2" + android:textAppearance="@style/TextAppearance.StatusBar.EventContent" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="-2dp" + android:layout_marginBottom="-2dp" + android:singleLine="true" + android:fadingEdge="horizontal" + android:ellipsize="marquee" + android:visibility="gone" + android:alpha="0.7" + /> <LinearLayout - android:layout_width="0dp" + android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_gravity="center_vertical" - android:layout_weight="1" - android:orientation="vertical" - android:paddingLeft="16dp" + android:orientation="horizontal" + android:alpha="0.7" > - <TextView android:id="@+id/title" - android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:singleLine="true" - android:ellipsize="marquee" - android:fadingEdge="horizontal" - android:layout_marginBottom="-3dp" - /> <TextView android:id="@+id/text" android:textAppearance="@style/TextAppearance.StatusBar.EventContent" - android:layout_width="match_parent" + android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" - android:layout_marginTop="-2dp" + android:layout_gravity="center" android:singleLine="true" android:ellipsize="marquee" android:fadingEdge="horizontal" /> + <TextView android:id="@+id/info" + android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:layout_weight="0" + android:singleLine="true" + android:gravity="center" + android:paddingLeft="8dp" + /> + <ImageView android:id="@+id/icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:layout_weight="0" + android:scaleType="center" + android:paddingLeft="8dp" + /> </LinearLayout> - <TextView android:id="@+id/info" - android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:singleLine="true" - android:gravity="center_vertical" - android:paddingLeft="4dp" - android:paddingRight="4dp" - /> - <ImageView android:id="@+id/icon" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="bottom" - android:layout_marginBottom="13dip" - android:scaleType="center" - /> </LinearLayout> - diff --git a/core/res/res/values-h720dp/dimens.xml b/core/res/res/values-h720dp/dimens.xml index c09cb5b..37dee8e 100644 --- a/core/res/res/values-h720dp/dimens.xml +++ b/core/res/res/values-h720dp/dimens.xml @@ -17,8 +17,6 @@ */ --> <resources> - <!-- Dialog title height --> - <dimen name="alert_dialog_title_height">54dip</dimen> <!-- Dialog button bar height --> <dimen name="alert_dialog_button_bar_height">54dip</dimen> <!-- Preference fragment padding, bottom --> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index f17a272..b87e99e 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -190,6 +190,8 @@ <string name="permdesc_receiveSms" msgid="6298292335965966117">"Aplikaciji omogućuje primanje i obradu SMS poruka. Zlonamjerne aplikacije mogu pratiti vaše poruke ili ih izbrisati prije nego što ih vi vidite."</string> <string name="permlab_receiveMms" msgid="8894700916188083287">"primanje MMS-a"</string> <string name="permdesc_receiveMms" msgid="4563346832000174373">"Aplikaciji omogućuje primanje i obradu MMS poruka. Zlonamjerne aplikacije mogu pratiti vaše poruke ili ih izbrisati prije nego što ih vi vidite."</string> + <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"primanje hitnih odašiljanja"</string> + <string name="permdesc_receiveEmergencyBroadcast" msgid="7118393393716546131">"Omogućuje aplikaciji primanje i obradu poruka hitnih odašiljanja. Ta je dozvola dostupna samo aplikacijama sustava."</string> <string name="permlab_sendSms" msgid="5600830612147671529">"slanje SMS poruka"</string> <string name="permdesc_sendSms" msgid="1946540351763502120">"Aplikaciji omogućuje slanje SMS poruka. Zlonamjerne aplikacije mogu stvarati troškove slanjem poruka bez vaše potvrde."</string> <string name="permlab_readSms" msgid="4085333708122372256">"čitanje SMS-a ili MMS-a"</string> diff --git a/core/res/res/values-sw600dp/styles.xml b/core/res/res/values-sw600dp/styles.xml index 7515c98..645db13 100644 --- a/core/res/res/values-sw600dp/styles.xml +++ b/core/res/res/values-sw600dp/styles.xml @@ -15,27 +15,6 @@ --> <resources> - <!-- Status Bar Styles --> - - <style name="TextAppearance.StatusBar"> - <item name="android:textAppearance">?android:attr/textAppearanceSmall</item> - </style> - <style name="TextAppearance.StatusBar.Ticker"> - </style> - <style name="TextAppearance.StatusBar.Title"> - <item name="android:textStyle">bold</item> - </style> - - <style name="TextAppearance.StatusBar.Icon"> - </style> - <style name="TextAppearance.StatusBar.EventContent"> - <item name="android:textColor">#ff999999</item> - <item name="android:textSize">14sp</item> - </style> - <style name="TextAppearance.StatusBar.EventContent.Title"> - <item name="android:textColor">?android:attr/textColorPrimary</item> - </style> - <style name="TextAppearance.Holo.Widget.TabWidget"> <item name="android:textSize">18sp</item> <item name="android:textStyle">normal</item> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 9c25ace..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" /> @@ -1206,6 +1211,16 @@ <enum name="vertical" value="1" /> </attr> + <!-- Alignment constants. --> + <attr name="alignmentMode"> + <!-- Align the bounds of the children. + See {@link android.widget.GridLayout#ALIGN_BOUNDS}. --> + <enum name="alignBounds" value="0" /> + <!-- Align the margins of the children. + See {@link android.widget.GridLayout#ALIGN_MARGINS}. --> + <enum name="alignMargins" value="1" /> + </attr> + <!-- ========================== --> <!-- Key Codes --> <!-- ========================== --> @@ -2541,12 +2556,12 @@ The default value is false. See {@link android.widget.GridLayout#setUseDefaultMargins(boolean)}.--> <attr name="useDefaultMargins" format="boolean" /> - <!-- When set to true, causes alignment to take place between the outer - boundary of a view, as defined by its margins. When set to false, + <!-- When set to alignMargins, causes alignment to take place between the outer + boundary of a view, as defined by its margins. When set to alignBounds, causes alignment to take place between the edges of the view. - The default is true. - See {@link android.widget.GridLayout#setMarginsIncludedInAlignment(boolean)}.--> - <attr name="marginsIncludedInAlignment" format="boolean" /> + The default is alignMargins. + See {@link android.widget.GridLayout#setAlignmentMode(int)}.--> + <attr name="alignmentMode" /> <!-- When set to true, forces row boundaries to appear in the same order as row indices. The default is false. diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml index 6529fe1..e76c0e5 100644 --- a/core/res/res/values/colors.xml +++ b/core/res/res/values/colors.xml @@ -148,5 +148,14 @@ <color name="group_button_dialog_pressed_holo_light">#ffffffff</color> <color name="group_button_dialog_focused_holo_light">#4699cc00</color> + + <!-- General purpose colors for Holo-themed elements --> + <eat-comment /> + + <!-- A Holo shade of blue --> + <color name="holo_blue">#ff6699ff</color> + <!-- A Holo shade of green --> + <color name="holo_green">#ff99cc00</color> + </resources> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 271ad8c..52b00c6 100755 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -82,7 +82,7 @@ <!-- The maximum width we would prefer dialogs to be. 0 if there is no maximum (let them grow as large as the screen). Actual values are specified for -large and -xlarge configurations. --> - <dimen name="config_prefDialogWidth">0px</dimen> + <dimen name="config_prefDialogWidth">320dp</dimen> <!-- Whether dialogs should close automatically when the user touches outside of them. This should not normally be modified. --> @@ -389,9 +389,11 @@ <!-- Control the behavior when the user long presses the power button. 0 - Nothing 1 - Recent apps dialog - 2 - Recent apps activity in SystemUI + 2 - Recent apps view in SystemUI + This needs to match the constants in + policy/src/com/android/internal/policy/impl/PhoneWindowManager.java --> - <integer name="config_longPressOnHomeBehavior">1</integer> + <integer name="config_longPressOnHomeBehavior">2</integer> <!-- Array of light sensor LUX values to define our levels for auto backlight brightness support. The N entries of this array define N + 1 zones as follows: @@ -634,10 +636,22 @@ <!-- Set to true if the RSSI should always display CDMA signal strength even on EVDO --> <bool name="config_alwaysUseCdmaRssi">false</bool> + <!-- If this value is true, duplicate Source/Destination port fields in WDP header of some carriers OMADM wap push are supported. ex: MSGTYPE-TotalSegments-CurrentSegment -SourcePortDestPort-SourcePortDestPort-OMADM PDU If false, not supported. --> <bool name="config_duplicate_port_omadm_wappush">false</bool> + + <!-- Maximum numerical value that will be shown in a status bar + notification icon or in the notification itself. Will be replaced + with @string/status_bar_notification_info_overflow when shown in the + UI. --> + <integer name="status_bar_notification_info_maxnum">999</integer> + + <!-- Path to an ISO image to be shared with via USB mass storage. + This is intended to allow packaging drivers or tools for installation on a PC. --> + <string translatable="false" name="config_isoImagePath"></string> + </resources> diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index c530632..20cb852 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -111,7 +111,7 @@ <dimen name="search_view_text_min_width">160dip</dimen> <!-- Dialog title height --> - <dimen name="alert_dialog_title_height">48dip</dimen> + <dimen name="alert_dialog_title_height">64dip</dimen> <!-- Dialog button bar height --> <dimen name="alert_dialog_button_bar_height">48dip</dimen> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 17b23da..e02496c 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -1733,7 +1733,7 @@ <public type="attr" name="columnCount" /> <public type="attr" name="columnOrderPreserved" /> <public type="attr" name="useDefaultMargins" /> - <public type="attr" name="marginsIncludedInAlignment" /> + <public type="attr" name="alignmentMode" /> <public type="attr" name="layout_row" /> <public type="attr" name="layout_rowSpan" /> @@ -1766,5 +1766,13 @@ <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" /> + + <public type="integer" name="status_bar_notification_info_maxnum" /> + <public type="string" name="status_bar_notification_info_overflow" /> </resources> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 34bc6bb..d9e7dac 100755 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -339,10 +339,12 @@ <!-- status message in phone options dialog for when airplane mode is off --> <string name="global_actions_airplane_mode_off_status">Airplane mode is OFF</string> - <!-- Text to use when the number in a notification info is too large (> 100). Most likely does not need - to be translated. We do this so, for example, if the user has tens of thousands of unread - emails, the whole notification isn't taken over by the number. [CHAR LIMIT=5] --> - <string name="status_bar_notification_info_overflow">100+</string> + <!-- Text to use when the number in a notification info is too large + (greater than status_bar_notification_info_maxnum, defined in + values/config.xml) and must be truncated. May need to be localized + for most appropriate textual indicator of "more than X". + [CHAR LIMIT=4] --> + <string name="status_bar_notification_info_overflow">999+</string> <!-- Displayed to the user to tell them that they have started up the phone in "safe mode" --> <string name="safeMode">Safe mode</string> @@ -901,16 +903,16 @@ contact (address) data stored on your phone. Malicious applications can use this to erase or modify your contact data.</string> - <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> + <!-- Title of the read profile permission, listed so the user can decide whether to allow the application to read the user's personal profile data. [CHAR LIMIT=30] --> <string name="permlab_readProfile">read profile data</string> - <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> + <!-- Description of the read profile permission, listed so the user can decide whether to allow the application to read the user's personal profile data. [CHAR LIMIT=NONE] --> <string name="permdesc_readProfile" product="default">Allows an application to read all of your personal profile information. Malicious applications can use this to identify you and send your personal information to other people.</string> - <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> + <!-- Title of the write profile permission, listed so the user can decide whether to allow the application to write to the user's personal profile data. [CHAR LIMIT=30] --> <string name="permlab_writeProfile">write profile data</string> - <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> + <!-- Description of the write profile permission, listed so the user can decide whether to allow the application to write to the user's personal profile data. [CHAR LIMIT=NONE] --> <string name="permdesc_writeProfile" product="default">Allows an application to modify your personal profile information. Malicious applications can use this to erase or modify your profile data.</string> @@ -1790,6 +1792,9 @@ <string name="lockscreen_missing_sim_instructions">Please insert a SIM card.</string> <!-- Shown in the lock screen to ask the user to insert a SIM card when sim is missing or not readable. --> <string name="lockscreen_missing_sim_instructions_long">The SIM card is missing or not readable. Please insert a SIM card.</string> + <!-- Shown in the lock screen to inform the user to SIM card is permanently disabled. --> + <string name="lockscreen_permanent_disabled_sim_instructions">Your SIM card is permanently disabled.\n + Please contact your wireless service provider to obtain another SIM card.</string> <!-- Shown in the lock screen when there is emergency calls only mode. --> <string name="emergency_calls_only" msgid="2485604591272668370">Emergency calls only</string> diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml index 19b05c9..72a5797 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -227,15 +227,15 @@ <style name="TextAppearance.StatusBar.Icon"> </style> <style name="TextAppearance.StatusBar.EventContent"> - <item name="android:textColor">#ff999999</item> - <item name="android:textSize">14sp</item> + <item name="android:textColor">?android:attr/textColorPrimary</item> + <item name="android:textSize">13sp</item> </style> <style name="TextAppearance.StatusBar.EventContent.Title"> - <item name="android:textColor">?android:attr/textColorPrimary</item> + <item name="android:textSize">16sp</item> + <item name="android:textStyle">bold</item> </style> <style name="TextAppearance.StatusBar.EventContent.Info"> - <item name="android:textAppearance">?android:attr/textAppearanceLarge</item> - <item name="android:textColor">#ff272727</item> + <item name="android:textSize">13sp</item> </style> <style name="TextAppearance.Small.CalendarViewWeekDayView"> @@ -1321,7 +1321,8 @@ </style> <style name="TextAppearance.Holo.DialogWindowTitle"> - <item name="android:textSize">18sp</item> + <item name="android:textSize">22sp</item> + <item name="android:textColor">@android:color/holo_blue</item> </style> <style name="TextAppearance.Holo.CalendarViewWeekDayView" parent="TextAppearance.Small.CalendarViewWeekDayView"> @@ -1419,7 +1420,8 @@ </style> <style name="TextAppearance.Holo.Light.DialogWindowTitle"> - <item name="android:textSize">18sp</item> + <item name="android:textSize">22sp</item> + <item name="android:textColor">@android:color/holo_blue</item> </style> <style name="TextAppearance.Holo.Light.CalendarViewWeekDayView" parent="TextAppearance.Small.CalendarViewWeekDayView"> @@ -1448,6 +1450,12 @@ <style name="Widget.Holo.Button.Borderless"> <item name="android:background">?android:attr/selectableItemBackground</item> + <item name="android:paddingLeft">4dip</item> + <item name="android:paddingRight">4dip</item> + </style> + + <style name="Widget.Holo.Button.Borderless.Small"> + <item name="android:textSize">14sp</item> </style> <style name="Widget.Holo.Button.Small"> @@ -1488,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"> @@ -1864,6 +1873,12 @@ <style name="Widget.Holo.Light.Button.Borderless"> <item name="android:background">?android:attr/selectableItemBackground</item> + <item name="android:paddingLeft">4dip</item> + <item name="android:paddingRight">4dip</item> + </style> + + <style name="Widget.Holo.Light.Button.Borderless.Small"> + <item name="android:textSize">14sp</item> </style> <style name="Widget.Holo.Light.Button.Small"> @@ -1891,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 5f77dc5..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> @@ -1411,6 +1417,7 @@ <item name="android:colorBackgroundCacheHint">@null</item> <item name="android:buttonBarStyle">@android:style/Holo.ButtonBar.AlertDialog</item> + <item name="borderlessButtonStyle">@android:style/Widget.Holo.Button.Borderless.Small</item> <item name="textAppearance">@android:style/TextAppearance.Holo</item> <item name="textAppearanceInverse">@android:style/TextAppearance.Holo.Inverse</item> @@ -1420,7 +1427,7 @@ a regular dialog. --> <style name="Theme.Holo.Dialog.MinWidth"> <item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item> - <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_major</item> + <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item> </style> <!-- Variation of Theme.Holo.Dialog that does not include a title bar. --> @@ -1433,7 +1440,7 @@ a regular dialog. --> <style name="Theme.Holo.Dialog.NoActionBar.MinWidth"> <item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item> - <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_major</item> + <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item> </style> <!-- Variation of Theme.Holo.Dialog that does not include a frame (or background). @@ -1460,7 +1467,7 @@ <item name="windowTitleStyle">@android:style/DialogWindowTitle.Holo</item> <item name="windowContentOverlay">@null</item> <item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item> - <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_major</item> + <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item> </style> <!-- Theme for a window that will be displayed either full-screen on @@ -1499,6 +1506,7 @@ <item name="android:colorBackgroundCacheHint">@null</item> <item name="android:buttonBarStyle">@android:style/Holo.Light.ButtonBar.AlertDialog</item> + <item name="borderlessButtonStyle">@android:style/Widget.Holo.Light.Button.Borderless.Small</item> <item name="textAppearance">@android:style/TextAppearance.Holo.Light</item> <item name="textAppearanceInverse">@android:style/TextAppearance.Holo.Light.Inverse</item> @@ -1508,7 +1516,7 @@ a regular dialog. --> <style name="Theme.Holo.Light.Dialog.MinWidth"> <item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item> - <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_major</item> + <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item> </style> <!-- Variation of Theme.Holo.Light.Dialog that does not include a title bar. --> @@ -1521,7 +1529,7 @@ a regular dialog. --> <style name="Theme.Holo.Light.Dialog.NoActionBar.MinWidth"> <item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item> - <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_major</item> + <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item> </style> <!-- Theme for a window that will be displayed either full-screen on @@ -1547,7 +1555,7 @@ <item name="windowTitleStyle">@android:style/DialogWindowTitle.Holo.Light</item> <item name="windowContentOverlay">@null</item> <item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item> - <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_major</item> + <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item> </style> <!-- Default holographic (dark) for windows that want to have the user's selected diff --git a/core/tests/coretests/src/android/content/res/ConfigurationTest.java b/core/tests/coretests/src/android/content/res/ConfigurationTest.java deleted file mode 100644 index 54a5e4e..0000000 --- a/core/tests/coretests/src/android/content/res/ConfigurationTest.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.content.res; - -import java.util.Locale; - -import android.test.AndroidTestCase; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetNew; - -public class ConfigurationTest extends AndroidTestCase { - - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getLayoutDirectionFromLocale", - args = {Locale.class} - ) - public void testGetLayoutDirectionFromLocale() { - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(null)); - - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.ENGLISH)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.CANADA)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.CANADA_FRENCH)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.FRANCE)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.FRENCH)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.GERMAN)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.GERMANY)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.ITALIAN)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.ITALY)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.UK)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.US)); - - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.ROOT)); - - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.CHINA)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.CHINESE)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.JAPAN)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.JAPANESE)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.KOREA)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.KOREAN)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.PRC)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.SIMPLIFIED_CHINESE)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.TAIWAN)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.TRADITIONAL_CHINESE)); - - Locale locale = new Locale("ar"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "AE"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "BH"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "DZ"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "EG"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "IQ"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "JO"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "KW"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "LB"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "LY"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "MA"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "OM"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "QA"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "SA"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "SD"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "SY"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "TN"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "YE"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - - locale = new Locale("fa"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("fa", "AF"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("fa", "IR"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - - locale = new Locale("iw"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("iw", "IL"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("he"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("he", "IL"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - - // The following test will not pass until we are able to take care about the scrip subtag - // thru having the "likelySubTags" file into ICU4C -// locale = new Locale("pa_Arab"); -// assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, -// Configuration.getLayoutDirectionFromLocale(locale)); -// locale = new Locale("pa_Arab", "PK"); -// assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, -// Configuration.getLayoutDirectionFromLocale(locale)); - - locale = new Locale("ps"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ps", "AF"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - - // The following test will not work as the localized display name would be "Urdu" with ICU 4.4 - // We will need ICU 4.6 to get the correct localized display name -// locale = new Locale("ur"); -// assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, -// Configuration.getLayoutDirectionFromLocale(locale)); -// locale = new Locale("ur", "IN"); -// assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, -// Configuration.getLayoutDirectionFromLocale(locale)); -// locale = new Locale("ur", "PK"); -// assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, -// Configuration.getLayoutDirectionFromLocale(locale)); - - // The following test will not pass until we are able to take care about the scrip subtag - // thru having the "likelySubTags" file into ICU4C -// locale = new Locale("uz_Arab"); -// assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, -// Configuration.getLayoutDirectionFromLocale(locale)); -// locale = new Locale("uz_Arab", "AF"); -// assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, -// Configuration.getLayoutDirectionFromLocale(locale)); - } -} diff --git a/core/tests/coretests/src/android/util/LocaleUtilTest.java b/core/tests/coretests/src/android/util/LocaleUtilTest.java new file mode 100644 index 0000000..203781f --- /dev/null +++ b/core/tests/coretests/src/android/util/LocaleUtilTest.java @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.util; + +import java.util.Locale; + +import android.test.AndroidTestCase; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetNew; + +import static android.util.LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE; +import static android.util.LocaleUtil.TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE; + +public class LocaleUtilTest extends AndroidTestCase { + + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getLayoutDirectionFromLocale", + args = {Locale.class} + ) + public void testGetLayoutDirectionFromLocale() { + assertEquals(TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(null)); + + assertEquals(TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.ENGLISH)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.CANADA)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.CANADA_FRENCH)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.FRANCE)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.FRENCH)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.GERMAN)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.GERMANY)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.ITALIAN)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.ITALY)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.UK)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.US)); + + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.ROOT)); + + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.CHINA)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.CHINESE)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.JAPAN)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.JAPANESE)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.KOREA)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.KOREAN)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.PRC)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.SIMPLIFIED_CHINESE)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.TAIWAN)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.TRADITIONAL_CHINESE)); + + Locale locale = new Locale("ar"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "AE"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "BH"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "DZ"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "EG"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "IQ"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "JO"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "KW"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "LB"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "LY"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "MA"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "OM"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "QA"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "SA"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "SD"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "SY"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "TN"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "YE"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + + locale = new Locale("fa"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("fa", "AF"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("fa", "IR"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + + locale = new Locale("iw"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("iw", "IL"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("he"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("he", "IL"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + + locale = new Locale("pa_Arab"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("pa_Arab", "PK"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + + locale = new Locale("ps"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ps", "AF"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + + locale = new Locale("ur"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ur", "IN"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ur", "PK"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + + locale = new Locale("uz_Arab"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("uz_Arab", "AF"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + + // Locale without a real language + locale = new Locale("zz"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + } +} 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/docs/html/resources/resources-data.js b/docs/html/resources/resources-data.js index 77aee46..097d004 100644 --- a/docs/html/resources/resources-data.js +++ b/docs/html/resources/resources-data.js @@ -407,6 +407,26 @@ var ANDROID_RESOURCES = [ } }, { + tags: ['sample', 'layout', 'ui', 'fragment', 'loader', 'new'], + path: 'samples/Support4Demos/index.html', + title: { + en: 'API 4+ Support Demos' + }, + description: { + en: 'A variety of small applications that demonstrate the use of the helper classes in the Android API 4+ Support Library (classes which work down to API level 4 or version 1.6 of the platform).' + } + }, + { + tags: ['sample', 'layout', 'ui', 'new'], + path: 'samples/Support13Demos/index.html', + title: { + en: 'API 13+ Support Demos' + }, + description: { + en: 'A variety of small applications that demonstrate the use of the helper classes in the Android API 13+ Support Library (classes which work down to API level 13 or version 3.2 of the platform).' + } + }, + { tags: ['sample', 'data', 'newfeature', 'accountsync'], path: 'samples/BackupRestore/index.html', title: { diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp index c37b4f8..458f1b6 100644 --- a/drm/common/IDrmManagerService.cpp +++ b/drm/common/IDrmManagerService.cpp @@ -37,7 +37,7 @@ using namespace android; -static void writeDecrptHandleToParcelData( +static void writeDecryptHandleToParcelData( const DecryptHandle* handle, Parcel* data) { data->writeInt32(handle->decryptId); data->writeString8(handle->mimeType); @@ -46,14 +46,14 @@ static void writeDecrptHandleToParcelData( int size = handle->copyControlVector.size(); data->writeInt32(size); - for(int i = 0; i < size; i++) { + for (int i = 0; i < size; i++) { data->writeInt32(handle->copyControlVector.keyAt(i)); data->writeInt32(handle->copyControlVector.valueAt(i)); } size = handle->extendedData.size(); data->writeInt32(size); - for(int i = 0; i < size; i++) { + for (int i = 0; i < size; i++) { data->writeString8(handle->extendedData.keyAt(i)); data->writeString8(handle->extendedData.valueAt(i)); } @@ -77,14 +77,14 @@ static void readDecryptHandleFromParcelData( handle->status = data.readInt32(); int size = data.readInt32(); - for (int i = 0; i < size; i ++) { + for (int i = 0; i < size; i++) { DrmCopyControl key = (DrmCopyControl)data.readInt32(); int value = data.readInt32(); handle->copyControlVector.add(key, value); } size = data.readInt32(); - for (int i = 0; i < size; i ++) { + for (int i = 0; i < size; i++) { String8 key = data.readString8(); String8 value = data.readString8(); handle->extendedData.add(key, value); @@ -416,7 +416,7 @@ status_t BpDrmManagerService::consumeRights( data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor()); data.writeInt32(uniqueId); - writeDecrptHandleToParcelData(decryptHandle, &data); + writeDecryptHandleToParcelData(decryptHandle, &data); data.writeInt32(action); data.writeInt32(static_cast< int>(reserve)); @@ -433,7 +433,7 @@ status_t BpDrmManagerService::setPlaybackStatus( data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor()); data.writeInt32(uniqueId); - writeDecrptHandleToParcelData(decryptHandle, &data); + writeDecryptHandleToParcelData(decryptHandle, &data); data.writeInt32(playbackStatus); data.writeInt64(position); @@ -646,7 +646,7 @@ status_t BpDrmManagerService::closeDecryptSession(int uniqueId, DecryptHandle* d data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor()); data.writeInt32(uniqueId); - writeDecrptHandleToParcelData(decryptHandle, &data); + writeDecryptHandleToParcelData(decryptHandle, &data); remote()->transact(CLOSE_DECRYPT_SESSION, data, &reply); @@ -662,7 +662,7 @@ status_t BpDrmManagerService::initializeDecryptUnit( data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor()); data.writeInt32(uniqueId); - writeDecrptHandleToParcelData(decryptHandle, &data); + writeDecryptHandleToParcelData(decryptHandle, &data); data.writeInt32(decryptUnitId); @@ -682,7 +682,7 @@ status_t BpDrmManagerService::decrypt( data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor()); data.writeInt32(uniqueId); - writeDecrptHandleToParcelData(decryptHandle, &data); + writeDecryptHandleToParcelData(decryptHandle, &data); data.writeInt32(decryptUnitId); data.writeInt32((*decBuffer)->length); @@ -715,7 +715,7 @@ status_t BpDrmManagerService::finalizeDecryptUnit( data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor()); data.writeInt32(uniqueId); - writeDecrptHandleToParcelData(decryptHandle, &data); + writeDecryptHandleToParcelData(decryptHandle, &data); data.writeInt32(decryptUnitId); @@ -733,7 +733,7 @@ ssize_t BpDrmManagerService::pread( data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor()); data.writeInt32(uniqueId); - writeDecrptHandleToParcelData(decryptHandle, &data); + writeDecryptHandleToParcelData(decryptHandle, &data); data.writeInt32(numBytes); data.writeInt64(offset); @@ -1244,7 +1244,7 @@ status_t BnDrmManagerService::onTransact( = openDecryptSession(uniqueId, fd, data.readInt64(), data.readInt64()); if (NULL != handle) { - writeDecrptHandleToParcelData(handle, reply); + writeDecryptHandleToParcelData(handle, reply); clearDecryptHandle(handle); delete handle; handle = NULL; } @@ -1262,7 +1262,7 @@ status_t BnDrmManagerService::onTransact( DecryptHandle* handle = openDecryptSession(uniqueId, uri.string()); if (NULL != handle) { - writeDecrptHandleToParcelData(handle, reply); + writeDecryptHandleToParcelData(handle, reply); clearDecryptHandle(handle); delete handle; handle = NULL; diff --git a/drm/java/android/drm/DrmInfoRequest.java b/drm/java/android/drm/DrmInfoRequest.java index 2222ae8..1429fa5 100755 --- a/drm/java/android/drm/DrmInfoRequest.java +++ b/drm/java/android/drm/DrmInfoRequest.java @@ -32,16 +32,16 @@ public class DrmInfoRequest { */ public static final int TYPE_REGISTRATION_INFO = 1; /** - * Acquires information for unregistering the DRM server. - */ + * Acquires information for unregistering the DRM server. + */ public static final int TYPE_UNREGISTRATION_INFO = 2; /** - * Acquires rights information. - */ + * Acquires rights information. + */ public static final int TYPE_RIGHTS_ACQUISITION_INFO = 3; /** - * Acquires the progress of the rights acquisition. - */ + * Acquires the progress of the rights acquisition. + */ public static final int TYPE_RIGHTS_ACQUISITION_PROGRESS_INFO = 4; /** diff --git a/drm/java/android/drm/DrmInfoStatus.java b/drm/java/android/drm/DrmInfoStatus.java index b04694b..5c12ae3 100755 --- a/drm/java/android/drm/DrmInfoStatus.java +++ b/drm/java/android/drm/DrmInfoStatus.java @@ -31,20 +31,20 @@ public class DrmInfoStatus { public static final int STATUS_ERROR = 2; /** - * The status of the communication. - */ + * The status of the communication. + */ public final int statusCode; /** - * The type of DRM information processed. - */ + * The type of DRM information processed. + */ public final int infoType; /** - * The MIME type of the content. - */ + * The MIME type of the content. + */ public final String mimeType; /** - * The processed data. - */ + * The processed data. + */ public final ProcessedData data; /** diff --git a/drm/libdrmframework/include/PlugInManager.h b/drm/libdrmframework/include/PlugInManager.h index 8029138..7bb143f 100644 --- a/drm/libdrmframework/include/PlugInManager.h +++ b/drm/libdrmframework/include/PlugInManager.h @@ -202,7 +202,7 @@ private: Vector<String8> getPlugInPathList(const String8& rsDirPath) { Vector<String8> fileList; DIR* pDir = opendir(rsDirPath.string()); - struct dirent* pEntry = new dirent(); + struct dirent* pEntry; while (NULL != pDir && NULL != (pEntry = readdir(pDir))) { if (!isPlugIn(pEntry)) { @@ -219,8 +219,6 @@ private: if (NULL != pDir) { closedir(pDir); } - delete pEntry; - pEntry = NULL; return fileList; } diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java index 0ffd201..6c7341f 100644 --- a/graphics/java/android/graphics/SurfaceTexture.java +++ b/graphics/java/android/graphics/SurfaceTexture.java @@ -66,11 +66,8 @@ public class SurfaceTexture { /** * This field is used by native code, do not access or modify. - * - * @hide */ - @SuppressWarnings({"UnusedDeclaration"}) - public int mSurfaceTexture; + private int mSurfaceTexture; /** * Callback interface for being notified that a new stream frame is available. 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/include/utils/BlobCache.h b/include/utils/BlobCache.h index 8f76d72..dc45ff0 100644 --- a/include/utils/BlobCache.h +++ b/include/utils/BlobCache.h @@ -82,6 +82,9 @@ private: BlobCache(const BlobCache&); void operator=(const BlobCache&); + // A random function helper to get around MinGW not having nrand48() + long int blob_random(); + // clean evicts a randomly chosen set of entries from the cache such that // the total size of all remaining entries is less than mMaxTotalSize/2. void clean(); diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp index a4c5b36..519b40e 100644 --- a/libs/gui/tests/SurfaceTextureClient_test.cpp +++ b/libs/gui/tests/SurfaceTextureClient_test.cpp @@ -590,7 +590,7 @@ TEST_F(SurfaceTextureClientTest, GetTransformMatrixSucceedsAfterFreeingBuffersWi // This test verifies that the buffer format can be queried immediately after // it is set. -TEST_F(SurfaceTextureClientTest, DISABLED_QueryFormatAfterSettingWorks) { +TEST_F(SurfaceTextureClientTest, QueryFormatAfterSettingWorks) { sp<ANativeWindow> anw(mSTC); int fmts[] = { // RGBA_8888 should not come first, as it's the default diff --git a/libs/gui/tests/SurfaceTexture_test.cpp b/libs/gui/tests/SurfaceTexture_test.cpp index 50af3bb..f6cefa6 100644 --- a/libs/gui/tests/SurfaceTexture_test.cpp +++ b/libs/gui/tests/SurfaceTexture_test.cpp @@ -542,11 +542,7 @@ TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferNpot) { EXPECT_TRUE(checkPixel(36, 22, 155, 29, 0, 255)); } -// XXX: This test is disabled because it it currently broken on all devices to -// which I have access. Some of the checkPixel calls are not correct because -// I just copied them from the npot test above and haven't bothered to figure -// out the correct values. -TEST_F(SurfaceTextureGLTest, DISABLED_TexturingFromCpuFilledYV12BufferPow2) { +TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferPow2) { const int texWidth = 64; const int texHeight = 64; @@ -576,18 +572,18 @@ TEST_F(SurfaceTextureGLTest, DISABLED_TexturingFromCpuFilledYV12BufferPow2) { drawTexture(); - EXPECT_TRUE(checkPixel( 0, 0, 255, 127, 255, 255)); - EXPECT_TRUE(checkPixel(63, 0, 0, 133, 0, 255)); + EXPECT_TRUE(checkPixel( 0, 0, 0, 133, 0, 255)); + EXPECT_TRUE(checkPixel(63, 0, 255, 127, 255, 255)); EXPECT_TRUE(checkPixel(63, 63, 0, 133, 0, 255)); EXPECT_TRUE(checkPixel( 0, 63, 255, 127, 255, 255)); - EXPECT_TRUE(checkPixel(22, 19, 247, 70, 255, 255)); - EXPECT_TRUE(checkPixel(45, 11, 209, 32, 235, 255)); - EXPECT_TRUE(checkPixel(52, 12, 100, 255, 73, 255)); - EXPECT_TRUE(checkPixel( 7, 32, 155, 0, 118, 255)); - EXPECT_TRUE(checkPixel(31, 54, 148, 71, 110, 255)); - EXPECT_TRUE(checkPixel(29, 28, 255, 127, 255, 255)); - EXPECT_TRUE(checkPixel(36, 41, 155, 29, 0, 255)); + EXPECT_TRUE(checkPixel(22, 19, 100, 255, 74, 255)); + EXPECT_TRUE(checkPixel(45, 11, 100, 255, 74, 255)); + EXPECT_TRUE(checkPixel(52, 12, 155, 0, 181, 255)); + EXPECT_TRUE(checkPixel( 7, 32, 150, 237, 170, 255)); + EXPECT_TRUE(checkPixel(31, 54, 0, 71, 117, 255)); + EXPECT_TRUE(checkPixel(29, 28, 0, 133, 0, 255)); + EXPECT_TRUE(checkPixel(36, 41, 100, 232, 255, 255)); } TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferWithCrop) { 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/libs/rs/Android.mk b/libs/rs/Android.mk index 9fabf8d..d9cc6b6 100644 --- a/libs/rs/Android.mk +++ b/libs/rs/Android.mk @@ -119,6 +119,7 @@ LOCAL_SRC_FILES:= \ driver/rsdBcc.cpp \ driver/rsdCore.cpp \ driver/rsdFrameBuffer.cpp \ + driver/rsdFrameBufferObj.cpp \ driver/rsdGL.cpp \ driver/rsdMesh.cpp \ driver/rsdMeshObj.cpp \ diff --git a/libs/rs/driver/rsdAllocation.cpp b/libs/rs/driver/rsdAllocation.cpp index 8bfc185..01a0cf6 100644 --- a/libs/rs/driver/rsdAllocation.cpp +++ b/libs/rs/driver/rsdAllocation.cpp @@ -19,6 +19,7 @@ #include "rsdBcc.h" #include "rsdRuntime.h" #include "rsdAllocation.h" +#include "rsdFrameBufferObj.h" #include "rsAllocation.h" @@ -244,6 +245,9 @@ bool rsdAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) { if (alloc->mHal.state.usageFlags & ~RS_ALLOCATION_USAGE_SCRIPT) { drv->uploadDeferred = true; } + + drv->readBackFBO = NULL; + return true; } @@ -269,6 +273,10 @@ void rsdAllocationDestroy(const Context *rsc, Allocation *alloc) { free(drv->mallocPtr); drv->mallocPtr = NULL; } + if (drv->readBackFBO != NULL) { + delete drv->readBackFBO; + drv->readBackFBO = NULL; + } free(drv); alloc->mHal.drv = NULL; } @@ -292,13 +300,52 @@ void rsdAllocationResize(const Context *rsc, const Allocation *alloc, } } +static void rsdAllocationSyncFromFBO(const Context *rsc, const Allocation *alloc) { + if (!alloc->getIsScript()) { + return; // nothing to sync + } + + RsdHal *dc = (RsdHal *)rsc->mHal.drv; + RsdFrameBufferObj *lastFbo = dc->gl.currentFrameBuffer; + + DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; + if (!drv->textureID && !drv->renderTargetID) { + return; // nothing was rendered here yet, so nothing to sync + } + if (drv->readBackFBO == NULL) { + drv->readBackFBO = new RsdFrameBufferObj(); + drv->readBackFBO->setColorTarget(drv, 0); + drv->readBackFBO->setDimensions(alloc->getType()->getDimX(), + alloc->getType()->getDimY()); + } + + // Bind the framebuffer object so we can read back from it + drv->readBackFBO->setActive(rsc); + + // Do the readback + glReadPixels(0, 0, alloc->getType()->getDimX(), alloc->getType()->getDimY(), + drv->glFormat, drv->glType, alloc->getPtr()); + + // Revert framebuffer to its original + lastFbo->setActive(rsc); +} void rsdAllocationSyncAll(const Context *rsc, const Allocation *alloc, RsAllocationUsageType src) { DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; - if (!drv->uploadDeferred) { + if (src == RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) { + if(!alloc->getIsRenderTarget()) { + rsc->setError(RS_ERROR_FATAL_DRIVER, + "Attempting to sync allocation from render target, " + "for non-render target allocation"); + } else if (alloc->getType()->getElement()->getKind() != RS_KIND_PIXEL_RGBA) { + rsc->setError(RS_ERROR_FATAL_DRIVER, "Cannot only sync from RGBA" + "render target"); + } else { + rsdAllocationSyncFromFBO(rsc, alloc); + } return; } @@ -382,7 +429,40 @@ void rsdAllocationData1D_alloc(const android::renderscript::Context *rsc, const android::renderscript::Allocation *dstAlloc, uint32_t dstXoff, uint32_t dstLod, uint32_t count, const android::renderscript::Allocation *srcAlloc, - uint32_t srcXoff, uint32_t srcLod){ + uint32_t srcXoff, uint32_t srcLod) { +} + +uint8_t *getOffsetPtr(const android::renderscript::Allocation *alloc, + uint32_t xoff, uint32_t yoff, uint32_t lod, + RsAllocationCubemapFace face) { + uint8_t *ptr = static_cast<uint8_t *>(alloc->getPtr()); + ptr += alloc->getType()->getLODOffset(lod, xoff, yoff); + + if (face != 0) { + uint32_t totalSizeBytes = alloc->getType()->getSizeBytes(); + uint32_t faceOffset = totalSizeBytes / 6; + ptr += faceOffset * (uint32_t)face; + } + return ptr; +} + + +void rsdAllocationData2D_alloc_script(const android::renderscript::Context *rsc, + const android::renderscript::Allocation *dstAlloc, + uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod, + RsAllocationCubemapFace dstFace, uint32_t w, uint32_t h, + const android::renderscript::Allocation *srcAlloc, + uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod, + RsAllocationCubemapFace srcFace) { + uint32_t elementSize = dstAlloc->getType()->getElementSizeBytes(); + for (uint32_t i = 0; i < h; i ++) { + uint8_t *dstPtr = getOffsetPtr(dstAlloc, dstXoff, dstYoff + i, dstLod, dstFace); + uint8_t *srcPtr = getOffsetPtr(srcAlloc, srcXoff, srcYoff + i, srcLod, srcFace); + memcpy(dstPtr, srcPtr, w * elementSize); + + LOGE("COPIED dstXoff(%u), dstYoff(%u), dstLod(%u), dstFace(%u), w(%u), h(%u), srcXoff(%u), srcYoff(%u), srcLod(%u), srcFace(%u)", + dstXoff, dstYoff, dstLod, dstFace, w, h, srcXoff, srcYoff, srcLod, srcFace); + } } void rsdAllocationData2D_alloc(const android::renderscript::Context *rsc, @@ -392,6 +472,14 @@ void rsdAllocationData2D_alloc(const android::renderscript::Context *rsc, const android::renderscript::Allocation *srcAlloc, uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod, RsAllocationCubemapFace srcFace) { + if (!dstAlloc->getIsScript() && !srcAlloc->getIsScript()) { + rsc->setError(RS_ERROR_FATAL_DRIVER, "Non-script allocation copies not " + "yet implemented."); + return; + } + rsdAllocationData2D_alloc_script(rsc, dstAlloc, dstXoff, dstYoff, + dstLod, dstFace, w, h, srcAlloc, + srcXoff, srcYoff, srcLod, srcFace); } void rsdAllocationData3D_alloc(const android::renderscript::Context *rsc, diff --git a/libs/rs/driver/rsdAllocation.h b/libs/rs/driver/rsdAllocation.h index 7555c4a..4fc4419 100644 --- a/libs/rs/driver/rsdAllocation.h +++ b/libs/rs/driver/rsdAllocation.h @@ -23,6 +23,8 @@ #include <GLES/gl.h> #include <GLES2/gl2.h> +class RsdFrameBufferObj; + struct DrvAllocation { // Is this a legal structure to be used as a texture source. // Initially this will require 1D or 2D and color data @@ -42,8 +44,9 @@ struct DrvAllocation { GLenum glType; GLenum glFormat; - bool uploadDeferred; + + RsdFrameBufferObj * readBackFBO; }; GLenum rsdTypeToGLType(RsDataType t); diff --git a/libs/rs/driver/rsdFrameBuffer.cpp b/libs/rs/driver/rsdFrameBuffer.cpp index ce72b5d..8c1b12d 100644 --- a/libs/rs/driver/rsdFrameBuffer.cpp +++ b/libs/rs/driver/rsdFrameBuffer.cpp @@ -17,6 +17,7 @@ #include "rsdCore.h" #include "rsdFrameBuffer.h" +#include "rsdFrameBufferObj.h" #include "rsdAllocation.h" #include "rsContext.h" @@ -28,133 +29,70 @@ using namespace android; using namespace android::renderscript; -struct DrvFrameBuffer { - GLuint mFBOId; -}; - -void checkError(const Context *rsc) { - GLenum status; - status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - switch (status) { - case GL_FRAMEBUFFER_COMPLETE: - break; - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: - rsc->setError(RS_ERROR_BAD_VALUE, - "Unable to set up render Target: RFRAMEBUFFER_INCOMPLETE_ATTACHMENT"); - break; - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: - rsc->setError(RS_ERROR_BAD_VALUE, - "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"); - break; - case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: - rsc->setError(RS_ERROR_BAD_VALUE, - "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS"); - break; - case GL_FRAMEBUFFER_UNSUPPORTED: - rsc->setError(RS_ERROR_BAD_VALUE, - "Unable to set up render Target: GL_FRAMEBUFFER_UNSUPPORTED"); - break; - } -} - - void setDepthAttachment(const Context *rsc, const FBOCache *fb) { + RsdFrameBufferObj *fbo = (RsdFrameBufferObj*)fb->mHal.drv; + + DrvAllocation *depth = NULL; if (fb->mHal.state.depthTarget.get() != NULL) { - DrvAllocation *drv = (DrvAllocation *)fb->mHal.state.depthTarget->mHal.drv; - - if (drv->textureID) { - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, - GL_TEXTURE_2D, drv->textureID, 0); - } else { - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, - GL_RENDERBUFFER, drv->renderTargetID); + depth = (DrvAllocation *)fb->mHal.state.depthTarget->mHal.drv; + + if (depth->uploadDeferred) { + rsdAllocationSyncAll(rsc, fb->mHal.state.depthTarget.get(), + RS_ALLOCATION_USAGE_SCRIPT); } - } else { - // Reset last attachment - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0); } + fbo->setDepthTarget(depth); } void setColorAttachment(const Context *rsc, const FBOCache *fb) { + RsdFrameBufferObj *fbo = (RsdFrameBufferObj*)fb->mHal.drv; // Now attach color targets for (uint32_t i = 0; i < fb->mHal.state.colorTargetsCount; i ++) { - uint32_t texID = 0; + DrvAllocation *color = NULL; if (fb->mHal.state.colorTargets[i].get() != NULL) { - DrvAllocation *drv = (DrvAllocation *)fb->mHal.state.colorTargets[i]->mHal.drv; - - if (drv->textureID) { - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, - GL_TEXTURE_2D, drv->textureID, 0); - } else { - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, - GL_RENDERBUFFER, drv->renderTargetID); - } - } else { - // Reset last attachment - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, - GL_RENDERBUFFER, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, - GL_TEXTURE_2D, 0, 0); - } - } -} - -bool renderToFramebuffer(const FBOCache *fb) { - if (fb->mHal.state.depthTarget.get() != NULL) { - return false; - } + color = (DrvAllocation *)fb->mHal.state.colorTargets[i]->mHal.drv; - for (uint32_t i = 0; i < fb->mHal.state.colorTargetsCount; i ++) { - if (fb->mHal.state.colorTargets[i].get() != NULL) { - return false; + if (color->uploadDeferred) { + rsdAllocationSyncAll(rsc, fb->mHal.state.colorTargets[i].get(), + RS_ALLOCATION_USAGE_SCRIPT); + } } + fbo->setColorTarget(color, i); } - return true; } - bool rsdFrameBufferInit(const Context *rsc, const FBOCache *fb) { - DrvFrameBuffer *drv = (DrvFrameBuffer *)calloc(1, sizeof(DrvFrameBuffer)); - if (drv == NULL) { + RsdFrameBufferObj *fbo = new RsdFrameBufferObj(); + if (fbo == NULL) { return false; } - fb->mHal.drv = drv; - drv->mFBOId = 0; + fb->mHal.drv = fbo; + + RsdHal *dc = (RsdHal *)rsc->mHal.drv; + dc->gl.currentFrameBuffer = fbo; return true; } void rsdFrameBufferSetActive(const Context *rsc, const FBOCache *fb) { - DrvFrameBuffer *drv = (DrvFrameBuffer *)fb->mHal.drv; - - bool framebuffer = renderToFramebuffer(fb); - if (!framebuffer) { - if(drv->mFBOId == 0) { - glGenFramebuffers(1, &drv->mFBOId); - } - glBindFramebuffer(GL_FRAMEBUFFER, drv->mFBOId); - - setDepthAttachment(rsc, fb); - setColorAttachment(rsc, fb); - - glViewport(0, 0, fb->mHal.state.colorTargets[0]->getType()->getDimX(), - fb->mHal.state.colorTargets[0]->getType()->getDimY()); - - checkError(rsc); - } else { - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glViewport(0, 0, rsc->getWidth(), rsc->getHeight()); + setDepthAttachment(rsc, fb); + setColorAttachment(rsc, fb); + + RsdFrameBufferObj *fbo = (RsdFrameBufferObj *)fb->mHal.drv; + if (fb->mHal.state.colorTargets[0].get()) { + fbo->setDimensions(fb->mHal.state.colorTargets[0]->getType()->getDimX(), + fb->mHal.state.colorTargets[0]->getType()->getDimY()); + } else if (fb->mHal.state.depthTarget.get()) { + fbo->setDimensions(fb->mHal.state.depthTarget->getType()->getDimX(), + fb->mHal.state.depthTarget->getType()->getDimY()); } + + fbo->setActive(rsc); } void rsdFrameBufferDestroy(const Context *rsc, const FBOCache *fb) { - DrvFrameBuffer *drv = (DrvFrameBuffer *)fb->mHal.drv; - if(drv->mFBOId != 0) { - glDeleteFramebuffers(1, &drv->mFBOId); - } - - free(fb->mHal.drv); + RsdFrameBufferObj *fbo = (RsdFrameBufferObj *)fb->mHal.drv; + delete fbo; fb->mHal.drv = NULL; } diff --git a/libs/rs/driver/rsdFrameBufferObj.cpp b/libs/rs/driver/rsdFrameBufferObj.cpp new file mode 100644 index 0000000..145bf34 --- /dev/null +++ b/libs/rs/driver/rsdFrameBufferObj.cpp @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2011 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. + */ + + +#include "rsdFrameBufferObj.h" +#include "rsdAllocation.h" + +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + +using namespace android; +using namespace android::renderscript; + +RsdFrameBufferObj::RsdFrameBufferObj() { + mFBOId = 0; + mWidth = 0; + mHeight = 0; + mColorTargetsCount = 1; + mColorTargets = new DrvAllocation*[mColorTargetsCount]; + for (uint32_t i = 0; i < mColorTargetsCount; i ++) { + mColorTargets[i] = 0; + } + mDepthTarget = NULL; + mDirty = true; +} + +RsdFrameBufferObj::~RsdFrameBufferObj() { + if(mFBOId != 0) { + glDeleteFramebuffers(1, &mFBOId); + } + delete [] mColorTargets; +} + +void RsdFrameBufferObj::checkError(const Context *rsc) { + GLenum status; + status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + switch (status) { + case GL_FRAMEBUFFER_COMPLETE: + break; + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: + rsc->setError(RS_ERROR_BAD_VALUE, + "Unable to set up render Target: RFRAMEBUFFER_INCOMPLETE_ATTACHMENT"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: + rsc->setError(RS_ERROR_BAD_VALUE, + "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: + rsc->setError(RS_ERROR_BAD_VALUE, + "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS"); + break; + case GL_FRAMEBUFFER_UNSUPPORTED: + rsc->setError(RS_ERROR_BAD_VALUE, + "Unable to set up render Target: GL_FRAMEBUFFER_UNSUPPORTED"); + break; + } +} + + +void RsdFrameBufferObj::setDepthAttachment() { + if (mDepthTarget != NULL) { + if (mDepthTarget->textureID) { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + GL_TEXTURE_2D, mDepthTarget->textureID, 0); + } else { + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + GL_RENDERBUFFER, mDepthTarget->renderTargetID); + } + } else { + // Reset last attachment + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0); + } +} + +void RsdFrameBufferObj::setColorAttachment() { + // Now attach color targets + for (uint32_t i = 0; i < mColorTargetsCount; i ++) { + if (mColorTargets[i] != NULL) { + if (mColorTargets[i]->textureID) { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, + GL_TEXTURE_2D, mColorTargets[i]->textureID, 0); + } else { + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, + GL_RENDERBUFFER, mColorTargets[i]->renderTargetID); + } + } else { + // Reset last attachment + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, + GL_RENDERBUFFER, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, + GL_TEXTURE_2D, 0, 0); + } + } +} + +bool RsdFrameBufferObj::renderToFramebuffer() { + if (mDepthTarget != NULL) { + return false; + } + + for (uint32_t i = 0; i < mColorTargetsCount; i ++) { + if (mColorTargets[i] != NULL) { + return false; + } + } + return true; +} + +void RsdFrameBufferObj::setActive(const Context *rsc) { + bool framebuffer = renderToFramebuffer(); + if (!framebuffer) { + if(mFBOId == 0) { + glGenFramebuffers(1, &mFBOId); + } + glBindFramebuffer(GL_FRAMEBUFFER, mFBOId); + + if (mDirty) { + setDepthAttachment(); + setColorAttachment(); + mDirty = false; + } + + glViewport(0, 0, mWidth, mHeight); + checkError(rsc); + } else { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glViewport(0, 0, rsc->getWidth(), rsc->getHeight()); + } +} diff --git a/libs/rs/driver/rsdFrameBufferObj.h b/libs/rs/driver/rsdFrameBufferObj.h new file mode 100644 index 0000000..c6e7deb --- /dev/null +++ b/libs/rs/driver/rsdFrameBufferObj.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2011 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. + */ + +#ifndef _RSD_FRAMEBUFFER_OBJ_H_ +#define _RSD_FRAMEBUFFER_OBJ_H_ + +#include <rsContext.h> + +class DrvAllocation; + +class RsdFrameBufferObj { +public: + RsdFrameBufferObj(); + ~RsdFrameBufferObj(); + + void setActive(const android::renderscript::Context *rsc); + void setColorTarget(DrvAllocation *color, uint32_t index) { + mColorTargets[index] = color; + mDirty = true; + } + void setDepthTarget(DrvAllocation *depth) { + mDepthTarget = depth; + mDirty = true; + } + void setDimensions(uint32_t width, uint32_t height) { + mWidth = width; + mHeight = height; + } +protected: + uint32_t mFBOId; + DrvAllocation **mColorTargets; + uint32_t mColorTargetsCount; + DrvAllocation *mDepthTarget; + + uint32_t mWidth; + uint32_t mHeight; + + bool mDirty; + + bool renderToFramebuffer(); + void checkError(const android::renderscript::Context *rsc); + void setColorAttachment(); + void setDepthAttachment(); +}; + +#endif //_RSD_FRAMEBUFFER_STATE_H_ diff --git a/libs/rs/driver/rsdGL.cpp b/libs/rs/driver/rsdGL.cpp index a70589b..3ff03b4 100644 --- a/libs/rs/driver/rsdGL.cpp +++ b/libs/rs/driver/rsdGL.cpp @@ -39,6 +39,7 @@ #include "rsContext.h" #include "rsdShaderCache.h" #include "rsdVertexArray.h" +#include "rsdFrameBufferObj.h" using namespace android; using namespace android::renderscript; @@ -294,6 +295,7 @@ bool rsdGLInit(const Context *rsc) { dc->gl.shaderCache = new RsdShaderCache(); dc->gl.vertexArrayState = new RsdVertexArrayState(); dc->gl.vertexArrayState->init(dc->gl.gl.maxVertexAttribs); + dc->gl.currentFrameBuffer = NULL; LOGV("initGLThread end %p", rsc); return true; diff --git a/libs/rs/driver/rsdGL.h b/libs/rs/driver/rsdGL.h index 01c8438..0d5b7e7 100644 --- a/libs/rs/driver/rsdGL.h +++ b/libs/rs/driver/rsdGL.h @@ -22,6 +22,7 @@ class RsdShaderCache; class RsdVertexArrayState; +class RsdFrameBufferObj; typedef void (* InvokeFunc_t)(void); typedef void (*WorkerCallback_t)(void *usr, uint32_t idx); @@ -68,6 +69,7 @@ typedef struct RsdGLRec { uint32_t height; RsdShaderCache *shaderCache; RsdVertexArrayState *vertexArrayState; + RsdFrameBufferObj *currentFrameBuffer; } RsdGL; diff --git a/libs/rs/driver/rsdMeshObj.cpp b/libs/rs/driver/rsdMeshObj.cpp index c220ac1..4315c0d 100644 --- a/libs/rs/driver/rsdMeshObj.cpp +++ b/libs/rs/driver/rsdMeshObj.cpp @@ -138,7 +138,10 @@ void RsdMeshObj::renderPrimitiveRange(const Context *rsc, uint32_t primIndex, ui for (uint32_t ct=0; ct < mRSMesh->mHal.state.vertexBuffersCount; ct++) { const Allocation *alloc = mRSMesh->mHal.state.vertexBuffers[ct].get(); - rsdAllocationSyncAll(rsc, alloc, RS_ALLOCATION_USAGE_SCRIPT); + DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; + if (drv->uploadDeferred) { + rsdAllocationSyncAll(rsc, alloc, RS_ALLOCATION_USAGE_SCRIPT); + } } // update attributes with either buffer information or data ptr based on their current state @@ -163,7 +166,9 @@ void RsdMeshObj::renderPrimitiveRange(const Context *rsc, uint32_t primIndex, ui const Allocation *idxAlloc = prim->mIndexBuffer.get(); if (idxAlloc) { DrvAllocation *drvAlloc = (DrvAllocation *)idxAlloc->mHal.drv; - rsdAllocationSyncAll(rsc, idxAlloc, RS_ALLOCATION_USAGE_SCRIPT); + if (drvAlloc->uploadDeferred) { + rsdAllocationSyncAll(rsc, idxAlloc, RS_ALLOCATION_USAGE_SCRIPT); + } if (drvAlloc->bufferID) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, drvAlloc->bufferID); diff --git a/libs/rs/driver/rsdRuntimeStubs.cpp b/libs/rs/driver/rsdRuntimeStubs.cpp index bd8b3c3..25302aa 100644 --- a/libs/rs/driver/rsdRuntimeStubs.cpp +++ b/libs/rs/driver/rsdRuntimeStubs.cpp @@ -95,6 +95,8 @@ static void SC_AllocationCopy1DRange(Allocation *dstAlloc, Allocation *srcAlloc, uint32_t srcOff, uint32_t srcMip) { GET_TLS(); + rsrAllocationCopy1DRange(rsc, dstAlloc, dstOff, dstMip, count, + srcAlloc, srcOff, srcMip); } static void SC_AllocationCopy2DRange(Allocation *dstAlloc, @@ -105,6 +107,11 @@ static void SC_AllocationCopy2DRange(Allocation *dstAlloc, uint32_t srcXoff, uint32_t srcYoff, uint32_t srcMip, uint32_t srcFace) { GET_TLS(); + rsrAllocationCopy2DRange(rsc, dstAlloc, + dstXoff, dstYoff, dstMip, dstFace, + width, height, + srcAlloc, + srcXoff, srcYoff, srcMip, srcFace); } diff --git a/libs/rs/rsFBOCache.cpp b/libs/rs/rsFBOCache.cpp index 6960ef2..c5c64c2 100644 --- a/libs/rs/rsFBOCache.cpp +++ b/libs/rs/rsFBOCache.cpp @@ -80,16 +80,6 @@ void FBOCache::setup(Context *rsc) { return; } - if (mHal.state.depthTarget.get() != NULL) { - mHal.state.depthTarget->syncAll(rsc, RS_ALLOCATION_USAGE_SCRIPT); - } - - for (uint32_t i = 0; i < mHal.state.colorTargetsCount; i ++) { - if (mHal.state.colorTargets[i].get() != NULL) { - mHal.state.colorTargets[i]->syncAll(rsc, RS_ALLOCATION_USAGE_SCRIPT); - } - } - rsc->mHal.funcs.framebuffer.setActive(rsc, this); mDirty = false; diff --git a/libs/utils/BlobCache.cpp b/libs/utils/BlobCache.cpp index 1298fa7..590576a 100644 --- a/libs/utils/BlobCache.cpp +++ b/libs/utils/BlobCache.cpp @@ -31,9 +31,13 @@ BlobCache::BlobCache(size_t maxKeySize, size_t maxValueSize, size_t maxTotalSize mMaxTotalSize(maxTotalSize), mTotalSize(0) { nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); +#ifdef _WIN32 + srand(now); +#else mRandState[0] = (now >> 0) & 0xFFFF; mRandState[1] = (now >> 16) & 0xFFFF; mRandState[2] = (now >> 32) & 0xFFFF; +#endif LOGV("initializing random seed using %lld", now); } @@ -148,11 +152,19 @@ size_t BlobCache::get(const void* key, size_t keySize, void* value, return valueBlobSize; } +long int BlobCache::blob_random() { +#ifdef _WIN32 + return rand(); +#else + return nrand48(mRandState); +#endif +} + void BlobCache::clean() { // Remove a random cache entry until the total cache size gets below half // the maximum total cache size. while (mTotalSize > mMaxTotalSize / 2) { - size_t i = size_t(nrand48(mRandState) % (mCacheEntries.size())); + size_t i = size_t(blob_random() % (mCacheEntries.size())); const CacheEntry& entry(mCacheEntries[i]); mTotalSize -= entry.getKey()->getSize() + entry.getValue()->getSize(); mCacheEntries.removeAt(i); 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/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java index d6e1346..f3a91c5 100755 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java @@ -1,57 +1,54 @@ /* * Copyright (C) 2008 The Android Open Source Project * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 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 + * 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. + * 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.mediaframeworktest; /** - * - * This class has the names of the all the activity name and variables - * in the instrumentation test. + * + * This class has the names of the all the activity name and variables in the + * instrumentation test. * */ public class MediaNames { - //A directory to hold all kinds of media files + // A directory to hold all kinds of media files public static final String MEDIA_SAMPLE_POOL = "/sdcard/media_api/samples/"; - //Audio files - public static final String MP3CBR = "/sdcard/media_api/music/MP3_256kbps_2ch.mp3"; - public static final String MP3VBR = "/sdcard/media_api/music/MP3_256kbps_2ch_VBR.mp3"; + // Audio files + public static final String MP3CBR = "/sdcard/media_api/music/MP3_48KHz_128kbps_s_1_17_CBR.mp3"; + public static final String MP3VBR = "/sdcard/media_api/music/MP3_48KHz_128kbps_s_1_17_VBR.mp3"; + public static final String MP3ABR = "/sdcard/media_api/music/MP3_48KHz_128kbps_s_1_17_ABR.mp3"; public static final String SHORTMP3 = "/sdcard/media_api/music/SHORTMP3.mp3"; public static final String MIDI = "/sdcard/media_api/music/ants.mid"; - public static final String WMA9 = "/sdcard/media_api/music/WMA9.wma"; - public static final String WMA10 = "/sdcard/media_api/music/WMA10.wma"; public static final String WAV = "/sdcard/media_api/music/rings_2ch.wav"; public static final String AMR = "/sdcard/media_api/music/test_amr_ietf.amr"; - public static final String OGG = "/sdcard/media_api/music/Revelation.ogg"; public static final String SINE_200_1000 = "/sdcard/media_api/music/sine_200+1000Hz_44K_mo.wav"; - + // public static final String OGG = + // "/sdcard/media_api/music/Revelation.ogg"; + public static final int MP3CBR_LENGTH = 71000; public static final int MP3VBR_LENGTH = 71000; public static final int SHORTMP3_LENGTH = 286; public static final int MIDI_LENGTH = 17000; - public static final int WMA9_LENGTH = 126559; - public static final int WMA10_LENGTH = 126559; public static final int AMR_LENGTH = 37000; - public static final int OGG_LENGTH = 4000; public static final int SEEK_TIME = 10000; - + public static final long PAUSE_WAIT_TIME = 3000; public static final long WAIT_TIME = 2000; public static final long WAIT_SNAPSHOT_TIME = 5000; - //local video + // local video public static final String VIDEO_MP4 = "/sdcard/media_api/video/MPEG4_320_AAC_64.mp4"; public static final String VIDEO_SHORT_3GP = "/sdcard/media_api/video/short.3gp"; public static final String VIDEO_LARGE_SIZE_3GP = "/sdcard/media_api/video/border_large.3gp"; @@ -59,185 +56,105 @@ public class MediaNames { public static final String VIDEO_H263_AMR = "/sdcard/media_api/video/H263_56_AMRNB_6.3gp"; public static final String VIDEO_H264_AAC = "/sdcard/media_api/video/H264_320_AAC_64.3gp"; public static final String VIDEO_H264_AMR = "/sdcard/media_api/video/H264_320_AMRNB_6.3gp"; - public static final String VIDEO_WMV = "/sdcard/media_api/video/bugs.wmv"; public static final String VIDEO_HIGHRES_H263 = "/sdcard/media_api/video/H263_500_AMRNB_12.3gp"; public static final String VIDEO_HIGHRES_MP4 = "/sdcard/media_api/video/H264_500_AAC_128.3gp"; - - //Media Recorder + public static final String VIDEO_WEBM = "/sdcard/media_api/video/big-buck-bunny_trailer.webm"; + + // Media Recorder public static final String RECORDER_OUTPUT = "/sdcard/media_api/recorderOutput.amr"; - //video thumbnail + // video thumbnail public static final String THUMBNAIL_OUTPUT = "/sdcard/media_api/videoThumbnail.png"; public static final String GOLDEN_THUMBNAIL_OUTPUT = "/sdcard/media_api/goldenThumbnail.png"; - public static final String GOLDEN_THUMBNAIL_OUTPUT_2 = "/sdcard/media_api/goldenThumbnail2.png"; - - //Metadata Utility - public static final String[] THUMBNAIL_CAPTURE_TEST_FILES = { - "/sdcard/media_api/metadata/test.mp4", - "/sdcard/media_api/metadata/test1.3gp", - "/sdcard/media_api/metadata/test2.3gp", - "/sdcard/media_api/metadata/test3.3gp", - "/sdcard/media_api/metadata/test4.3gp", - "/sdcard/media_api/metadata/test5.3gp", - "/sdcard/media_api/metadata/test6.3gp", - "/sdcard/media_api/metadata/test7.3gp", - "/sdcard/media_api/metadata/test8.3gp", - "/sdcard/media_api/metadata/test9.3gp", - "/sdcard/media_api/metadata/test10.3gp", - "/sdcard/media_api/metadata/test11.3gp", - "/sdcard/media_api/metadata/test12.3gp", - "/sdcard/media_api/metadata/test13.3gp", - "/sdcard/media_api/metadata/test14.3gp", - "/sdcard/media_api/metadata/test15.3gp", - "/sdcard/media_api/metadata/test16.3gp", - "/sdcard/media_api/metadata/test17.3gp", - "/sdcard/media_api/metadata/test18.3gp", - "/sdcard/media_api/metadata/test19.3gp", - "/sdcard/media_api/metadata/test20.3gp", - "/sdcard/media_api/metadata/test21.3gp", - "/sdcard/media_api/metadata/test22.3gp", - "/sdcard/media_api/metadata/test23.3gp", - "/sdcard/media_api/metadata/test24.3gp", - "/sdcard/media_api/metadata/test25.3gp", - "/sdcard/media_api/metadata/test26.3gp", - "/sdcard/media_api/metadata/test27.3gp", - "/sdcard/media_api/metadata/test28.3gp", - "/sdcard/media_api/metadata/test29.3gp", - "/sdcard/media_api/metadata/test30.3gp", - "/sdcard/media_api/metadata/test31.3gp", - "/sdcard/media_api/metadata/test32.3gp", - "/sdcard/media_api/metadata/test33.3gp", - "/sdcard/media_api/metadata/test35.mp4", - "/sdcard/media_api/metadata/test36.m4v", - "/sdcard/media_api/metadata/test34.wmv", - "/sdcard/media_api/metadata/test_metadata.mp4", - }; - - public static final String[] METADATA_RETRIEVAL_TEST_FILES = { - // Raw AAC is not supported - // "/sdcard/media_api/test_raw.aac", - // "/sdcard/media_api/test_adts.aac", - // "/sdcard/media_api/test_adif.aac", - "/sdcard/media_api/metadata/test_metadata.mp4", - "/sdcard/media_api/metadata/WMA10.wma", - "/sdcard/media_api/metadata/Leadsol_out.wav", - "/sdcard/media_api/metadata/test_aac.mp4", - "/sdcard/media_api/metadata/test_amr.mp4", - "/sdcard/media_api/metadata/test_avc_amr.mp4", - "/sdcard/media_api/metadata/test_metadata.mp4", - "/sdcard/media_api/metadata/test_vbr.mp3", - "/sdcard/media_api/metadata/test_cbr.mp3", - "/sdcard/media_api/metadata/metadata_test1.mp3", - "/sdcard/media_api/metadata/test33.3gp", - "/sdcard/media_api/metadata/test35.mp4", - "/sdcard/media_api/metadata/test36.m4v", - "/sdcard/media_api/metadata/test_m4v_amr.mp4", - "/sdcard/media_api/metadata/test_h263_amr.mp4", - "/sdcard/media_api/metadata/test34.wmv", - }; - - public static final String[] ALBUMART_TEST_FILES = { - "/sdcard/media_api/album_photo/test_22_16_mp3.mp3", - "/sdcard/media_api/album_photo/PD_256kbps_48khz_mono_CBR_MCA.mp3", - "/sdcard/media_api/album_photo/PD_256kbps_44.1khz_mono_CBR_DPA.mp3", - "/sdcard/media_api/album_photo/PD_192kbps_32khz_mono_CBR_DPA.mp3", - "/sdcard/media_api/album_photo/NIN_256kbps_48khz_mono_CBR_MCA.mp3", - "/sdcard/media_api/album_photo/NIN_256kbps_44.1khz_mono_CBR_MCA.mp3", - "/sdcard/media_api/album_photo/NIN_112kbps(96kbps)_48khz_stereo_VBR_MCA.mp3", - "/sdcard/media_api/album_photo/NIN_112kbps(96kbps)_44.1khz_stereo_VBR_MCA.mp3", - "/sdcard/media_api/album_photo/lightGreen1.mp3", - "/sdcard/media_api/album_photo/babyBlue2 1.mp3", - "/sdcard/media_api/album_photo/2-01 01 NIN_56kbps(64kbps)_32khz_stereo_VBR_MCA.mp3", - "/sdcard/media_api/album_photo/02_NIN_112kbps(80kbps)_32khz_stereo_VBR_MCA.mp3", - "/sdcard/media_api/album_photo/No_Woman_No_Cry_128K.wma", - "/sdcard/media_api/album_photo/Beethoven_2.wma", - }; - - //TEST_PATH_1: is a video and contains metadata for key "num-tracks" - // TEST_PATH_2: any valid media file. - // TEST_PATH_3: invalid media file - public static final String TEST_PATH_1 = "/sdcard/media_api/metadata/test.mp4"; - public static final String TEST_PATH_3 = "/sdcard/media_api/data.txt"; - public static final String TEST_PATH_4 = "somenonexistingpathname"; - public static final String TEST_PATH_5 = "mem://012345"; - - //Meta data expected result - //The expected tag result in the following order - //cd_track_number, album, artist, author, composer, date, genre - //title, years, duration - public static final String META_DATA_MP3 [][] = { - {"/sdcard/media_api/metaDataTestMedias/MP3/ID3V1_ID3V2.mp3", "1/10", "ID3V2.3 Album", "ID3V2.3 Artist", - "ID3V2.3 Lyricist", "ID3V2.3 Composer", null, "Blues", - "ID3V2.3 Title", "1234", "295", "1", null}, - {"/sdcard/media_api/metaDataTestMedias/MP3/ID3V2.mp3", "1/10", "ID3V2.3 Album", "ID3V2.3 Artist", - "ID3V2.3 Lyricist", "ID3V2.3 Composer", null, "Blues", - "ID3V2.3 Title", "1234", "287", "1", null}, - {"/sdcard/media_api/metaDataTestMedias/MP3/ID3V1.mp3", "1", "test ID3V1 Album", "test ID3V1 Artist", - null, null, null, "255", "test ID3V1 Title", "1234", "231332", "1", null}, - {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V1.mp3" , null, null, null, - null, null, null, null, null, null, "231330", "1", null}, - //The corrupted TALB field in id3v2 would not switch to id3v1 tag automatically - {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TALB.mp3", "01", null, "ID3V2.3 Artist", - "ID3V2.3 Lyricist", "ID3V2.3 Composer", null, - "Blues", "ID3V2.3 Title", "1234", "295", "1", null}, - {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TCOM.mp3", "01", "ID3V2.3 Album", - "ID3V2.3 Artist", "ID3V2.3 Lyricist", null, null, - "Blues", "ID3V2.3 Title", "1234", "295", "1", null}, - {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TCOM_2.mp3", "01", "ID3V2.3 Album", - "ID3V2.3 Artist", null, null, null, "Blues", "ID3V2.3 Title", "1234", "295", "1", null}, - {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TRCK.mp3", "dd", "ID3V2.3 Album", - "ID3V2.3 Artist", "ID3V2.3 Lyricist", "ID3V2.3 Composer", null, - "Blues", "ID3V2.3 Title", "1234", "295", "1", null}, - {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TRCK_2.mp3", "01", "ID3V2.3 Album", - "ID3V2.3 Artist", null, null, null, null, "ID3V2.3 Title", null, "295", "1", null}, - {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TYER.mp3", "01", "ID3V2.3 Album", - "ID3V2.3 Artist", null, null, null, null, "ID3V2.3 Title", "9999", "295", "1", null}, - {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TYER_2.mp3", "01", "ID3V2.3 Album", - "ID3V2.3 Artist", "ID3V2.3 Lyricist", "ID3V2.3 Composer", null, - "Blues", "ID3V2.3 Title", null, "295", "1", null}, - {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TIT.mp3", null, null, null, - null, null, null, null, null, null, "295", "1", null} - }; - - //output recorded video - - public static final String RECORDED_HVGA_H263 = "/sdcard/HVGA_H263.3gp"; - public static final String RECORDED_QVGA_H263 = "/sdcard/QVGA_H263.3gp"; - public static final String RECORDED_SQVGA_H263 = "/sdcard/SQVGA_H263.3gp"; - public static final String RECORDED_CIF_H263 = "/sdcard/CIF_H263.3gp"; - public static final String RECORDED_QCIF_H263 = "/sdcard/QCIF_H263.3gp"; - public static final String RECORDED_PORTRAIT_H263 = "/sdcard/QCIF_mp4.3gp"; - - public static final String RECORDED_HVGA_MP4 = "/sdcard/HVGA_mp4.mp4"; - public static final String RECORDED_QVGA_MP4 = "/sdcard/QVGA_mp4.mp4"; - public static final String RECORDED_SQVGA_MP4 = "/sdcard/SQVGA_mp4.mp4"; - public static final String RECORDED_CIF_MP4 = "/sdcard/CIF_mp4.mp4"; - public static final String RECORDED_QCIF_MP4 = "/sdcard/QCIF_mp4.mp4"; - - public static final String RECORDED_VIDEO_3GP = "/sdcard/temp.3gp"; - - public static final String INVALD_VIDEO_PATH = "/sdcard/media_api/filepathdoesnotexist" + - "/filepathdoesnotexist/temp.3gp"; - - - public static final long RECORDED_TIME = 5000; - public static final long VALID_VIDEO_DURATION = 2000; - - //Streaming test files - public static final byte [] STREAM_SERVER = new byte[] {(byte)75,(byte)17,(byte)48,(byte)204}; - public static final String STREAM_H264_480_360_1411k = - "http://75.17.48.204:10088/yslau/stress_media/h264_regular.mp4"; - public static final String STREAM_WMV = - "http://75.17.48.204:10088/yslau/stress_media/bugs.wmv"; - public static final String STREAM_H263_176x144_325k = - "http://75.17.48.204:10088/yslau/stress_media/h263_regular.3gp"; - public static final String STREAM_H264_352x288_1536k = - "http://75.17.48.204:10088/yslau/stress_media/h264_highBitRate.mp4"; - public static final String STREAM_MP3= - "http://75.17.48.204:10088/yslau/stress_media/mp3_regular.mp3"; - public static final String STREAM_MPEG4_QVGA_128k = - "http://75.17.48.204:10088/yslau/stress_media/mpeg4_qvga_24fps.3gp"; - public static final int STREAM_H264_480_360_1411k_DURATION = 46000; - public static final int VIDEO_H263_AAC_DURATION = 501000; - public static final int VIDEO_H263_AMR_DURATION = 502000; + + /* + * Metadata Utility Test media files which contain meta data. + */ + public static final String[] THUMBNAIL_METADATA_TEST_FILES = { + "/sdcard/media_api/video/H263_500_AMRNB_12.3gp", + "/sdcard/media_api/video/H263_56_AAC_24.3gp", + "/sdcard/media_api/video/H263_56_AMRNB_6.3gp", + "/sdcard/media_api/video/H264_320_AAC_64.3gp", + "/sdcard/media_api/video/H264_320_AMRNB_6.3gp", + "/sdcard/media_api/video/H264_500_AAC_128.3gp", + "/sdcard/media_api/video/H264_HVGA_500_NO_AUDIO.3gp", + "/sdcard/media_api/video/H264_QVGA_500_NO_AUDIO.3gp", + "/sdcard/media_api/video/MPEG4_320_AAC_64.mp4", + "/sdcard/media_api/video/border_large.3gp", + "/sdcard/media_api/videoeditor/H264_BP_800x480_15fps_512kbps_AACLC_24KHz_38Kbps_s_1_17.mp4", + "/sdcard/media_api/videoeditor/H264_MP_960x720_25fps_800kbps_AACLC_48Khz_192Kbps_s_1_17.mp4", + "/sdcard/media_api/videoeditor/MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4", + "/sdcard/media_api/videoeditor/MPEG4_SP_176x144_12fps_92kbps_AMRNB_8KHz_12.2kbps_m_0_27.3gp", + "/sdcard/media_api/videoeditor/MPEG4_SP_720x480_30fps_280kbps_AACLC_48kHz_161kbps_s_0_26.mp4" + }; + + public static final String[] ALBUMART_TEST_FILES = { + "/sdcard/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V1_ID3V2.mp3", + "/sdcard/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V2.mp3", + "/sdcard/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V1.mp3", + }; + + // TEST_PATH_1: is a video and contains metadata for key "num-tracks" + // TEST_PATH_2: any valid media file. + // TEST_PATH_3: invalid media file + public static final String TEST_PATH_1 = "/sdcard/media_api/video/MPEG4_320_AAC_64.mp4"; + public static final String TEST_PATH_3 = "/sdcard/media_api/data.txt"; + public static final String TEST_PATH_4 = "somenonexistingpathname"; + public static final String TEST_PATH_5 = "mem://012345"; + + // Meta data expected result + // The expected tag result in the following order + // cd_track_number, album, artist, author, composer, date, genre + // title, years, duration + public static final String META_DATA_MP3[][] = { + {"/sdcard/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V1_ID3V2.mp3", "2/34", + "Test ID3V2 Album", "Test ID3V2 Artist", null, "Test ID3V2 Composer", + null, "(1)Classic Rock", "Test ID3V2 Title ", null, "77640", "1", null}, + {"/sdcard/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V2.mp3", "1/10", + "Test ID3V2 Album", "Test ID3V2 Artist", null, "Test ID3V2 Composer", + null, "(74)Acid Jazz", "Test ID3V2 Tag", null, "77640", "1", null}, + {"/sdcard/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V1.mp3", "2", + "Test ID3V1 Album", "Test ID3V1 Artist", null, null, null, "(15)", + "Test ID3V1 Title", "2011", "77640", "1", null} + }; + + // output recorded video + public static final String RECORDED_HVGA_H263 = "/sdcard/HVGA_H263.3gp"; + public static final String RECORDED_QVGA_H263 = "/sdcard/QVGA_H263.3gp"; + public static final String RECORDED_SQVGA_H263 = "/sdcard/SQVGA_H263.3gp"; + public static final String RECORDED_CIF_H263 = "/sdcard/CIF_H263.3gp"; + public static final String RECORDED_QCIF_H263 = "/sdcard/QCIF_H263.3gp"; + public static final String RECORDED_PORTRAIT_H263 = "/sdcard/QCIF_mp4.3gp"; + + public static final String RECORDED_HVGA_MP4 = "/sdcard/HVGA_mp4.mp4"; + public static final String RECORDED_QVGA_MP4 = "/sdcard/QVGA_mp4.mp4"; + public static final String RECORDED_SQVGA_MP4 = "/sdcard/SQVGA_mp4.mp4"; + public static final String RECORDED_CIF_MP4 = "/sdcard/CIF_mp4.mp4"; + public static final String RECORDED_QCIF_MP4 = "/sdcard/QCIF_mp4.mp4"; + + public static final String RECORDED_VIDEO_3GP = "/sdcard/temp.3gp"; + + public static final String INVALD_VIDEO_PATH = + "/sdcard/media_api/filepathdoesnotexist" + "/filepathdoesnotexist/temp.3gp"; + + public static final long RECORDED_TIME = 5000; + public static final long VALID_VIDEO_DURATION = 2000; + + // Streaming test files + public static final byte[] STREAM_SERVER = + new byte[] {(byte) 75, (byte) 17, (byte) 48, (byte) 204}; + public static final String STREAM_H264_480_360_1411k = + "http://75.17.48.204:10088/yslau/stress_media/h264_regular.mp4"; + public static final String STREAM_WMV = "http://75.17.48.204:10088/yslau/stress_media/bugs.wmv"; + public static final String STREAM_H263_176x144_325k = + "http://75.17.48.204:10088/yslau/stress_media/h263_regular.3gp"; + public static final String STREAM_H264_352x288_1536k = + "http://75.17.48.204:10088/yslau/stress_media/h264_highBitRate.mp4"; + public static final String STREAM_MP3 = + "http://75.17.48.204:10088/yslau/stress_media/mp3_regular.mp3"; + public static final String STREAM_MPEG4_QVGA_128k = + "http://75.17.48.204:10088/yslau/stress_media/mpeg4_qvga_24fps.3gp"; + public static final int STREAM_H264_480_360_1411k_DURATION = 46000; + public static final int VIDEO_H263_AAC_DURATION = 501000; + public static final int VIDEO_H263_AMR_DURATION = 502000; } diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java index 00e0a52..380de9c 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java @@ -41,10 +41,7 @@ public class MediaMetadataTest extends AndroidTestCase { } public static enum MP3_TEST_FILE{ - ID3V1V2, ID3V2, ID3V1, - CORRUPTED_ID3V1, CORRUPTED_ID3V2_TALB, CORRUPTED_ID3V2_TCOM, - CORRUPTED_ID3V2_TCOM_2, CORRUPTED_ID3V2_TRCK, CORRUPTED_D3V2_TRCK_2, - CORRUPTED_ID3V2_TYER, CORRUPTED_ID3V2_TYER_2, CORRUPTED_ID3V2_TIT + ID3V1V2, ID3V2, ID3V1 } public static METADATA_EXPECTEDRESULT meta; @@ -64,53 +61,7 @@ public class MediaMetadataTest extends AndroidTestCase { public static void testID3V1Metadata() throws Exception { validateMetatData(mp3_test_file.ID3V1.ordinal(), MediaNames.META_DATA_MP3); } - - @MediumTest - public static void testCorruptedID3V1Metadata() throws Exception { - validateMetatData(mp3_test_file.CORRUPTED_ID3V1.ordinal(), MediaNames.META_DATA_MP3); - } - @MediumTest - public static void testCorrupted_ID3V2_TALBMetadata() throws Exception { - validateMetatData(mp3_test_file.CORRUPTED_ID3V2_TALB.ordinal(), MediaNames.META_DATA_MP3); - } - - @MediumTest - public static void testCorrupted_ID3V2_TCOMMetadata() throws Exception { - validateMetatData(mp3_test_file.CORRUPTED_ID3V2_TCOM.ordinal(), MediaNames.META_DATA_MP3); - } - - @MediumTest - public static void testCorrupted_ID3V2_TCOMM2etadata() throws Exception { - validateMetatData(mp3_test_file.CORRUPTED_ID3V2_TCOM_2.ordinal(), MediaNames.META_DATA_MP3); - } - - @MediumTest - public static void testCorrupted_ID3V2_TRCKMetadata() throws Exception { - validateMetatData(mp3_test_file.CORRUPTED_ID3V2_TRCK.ordinal(), MediaNames.META_DATA_MP3); - } - - @MediumTest - public static void testCorrupted_ID3V2_TRCK2Metadata() throws Exception { - validateMetatData(mp3_test_file.CORRUPTED_D3V2_TRCK_2.ordinal(), MediaNames.META_DATA_MP3); - } - - @MediumTest - public static void testCorrupted_ID3V2_TYERMetadata() throws Exception { - validateMetatData(mp3_test_file.CORRUPTED_ID3V2_TYER.ordinal(), MediaNames.META_DATA_MP3); - } - - @MediumTest - public static void testCorrupted_ID3V2_TYER2Metadata() throws Exception { - validateMetatData(mp3_test_file.CORRUPTED_ID3V2_TYER_2.ordinal(), MediaNames.META_DATA_MP3); - } - - @MediumTest - public static void testCorrupted_ID3V2_TITMetadata() throws Exception { - validateMetatData(mp3_test_file.CORRUPTED_ID3V2_TIT.ordinal(), MediaNames.META_DATA_MP3); - } - - private static void validateMetatData(int fileIndex, String meta_data_file[][]) { Log.v(TAG, "filePath = "+ meta_data_file[fileIndex][0]); if ((meta_data_file[fileIndex][0].endsWith("wma") && !MediaProfileReader.getWMAEnable()) || diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java index 3a9564d..57d5368 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java @@ -84,15 +84,6 @@ public class MediaPlayerApiTest extends ActivityInstrumentationTestCase<MediaFra duratoinWithinTolerence = verifyDuration(duration, MediaNames.MIDI_LENGTH); assertTrue("MIDI getDuration", duratoinWithinTolerence); } - - @MediumTest - public void testWMA9GetDuration() throws Exception { - if (isWMAEnable) { - int duration = CodecTest.getDuration(MediaNames.WMA9); - duratoinWithinTolerence = verifyDuration(duration, MediaNames.WMA9_LENGTH); - assertTrue("WMA9 getDuration", duratoinWithinTolerence); - } - } @MediumTest public void testAMRGetDuration() throws Exception { @@ -127,15 +118,7 @@ public class MediaPlayerApiTest extends ActivityInstrumentationTestCase<MediaFra boolean currentPosition = CodecTest.getCurrentPosition(MediaNames.MIDI); assertTrue("MIDI GetCurrentPosition", currentPosition); } - - @LargeTest - public void testWMA9GetCurrentPosition() throws Exception { - if (isWMAEnable) { - boolean currentPosition = CodecTest.getCurrentPosition(MediaNames.WMA9); - assertTrue("WMA9 GetCurrentPosition", currentPosition); - } - } - + @LargeTest public void testAMRGetCurrentPosition() throws Exception { boolean currentPosition = CodecTest.getCurrentPosition(MediaNames.AMR); @@ -166,15 +149,7 @@ public class MediaPlayerApiTest extends ActivityInstrumentationTestCase<MediaFra boolean isPaused = CodecTest.pause(MediaNames.MIDI); assertTrue("MIDI Pause", isPaused); } - - @LargeTest - public void testWMA9Pause() throws Exception { - if (isWMAEnable) { - boolean isPaused = CodecTest.pause(MediaNames.WMA9); - assertTrue("WMA9 Pause", isPaused); - } - } - + @LargeTest public void testAMRPause() throws Exception { boolean isPaused = CodecTest.pause(MediaNames.AMR); @@ -239,15 +214,7 @@ public class MediaPlayerApiTest extends ActivityInstrumentationTestCase<MediaFra boolean isLoop = CodecTest.setLooping(MediaNames.MIDI); assertTrue("MIDI setLooping", isLoop); } - - @LargeTest - public void testWMA9SetLooping() throws Exception { - if (isWMAEnable) { - boolean isLoop = CodecTest.setLooping(MediaNames.WMA9); - assertTrue("WMA9 setLooping", isLoop); - } - } - + @LargeTest public void testAMRSetLooping() throws Exception { boolean isLoop = CodecTest.setLooping(MediaNames.AMR); @@ -279,15 +246,7 @@ public class MediaPlayerApiTest extends ActivityInstrumentationTestCase<MediaFra boolean isLoop = CodecTest.seekTo(MediaNames.MIDI); assertTrue("MIDI seekTo", isLoop); } - - @LargeTest - public void testWMA9SeekTo() throws Exception { - if (isWMAEnable) { - boolean isLoop = CodecTest.seekTo(MediaNames.WMA9); - assertTrue("WMA9 seekTo", isLoop); - } - } - + @LargeTest public void testAMRSeekTo() throws Exception { boolean isLoop = CodecTest.seekTo(MediaNames.AMR); @@ -320,15 +279,6 @@ public class MediaPlayerApiTest extends ActivityInstrumentationTestCase<MediaFra boolean isEnd = CodecTest.seekToEnd(MediaNames.MIDI); assertTrue("MIDI seekToEnd", isEnd); } - - @Suppress - @LargeTest - public void testWMA9SeekToEnd() throws Exception { - if (isWMAEnable) { - boolean isEnd = CodecTest.seekToEnd(MediaNames.WMA9); - assertTrue("WMA9 seekToEnd", isEnd); - } - } @LargeTest public void testAMRSeekToEnd() throws Exception { @@ -393,17 +343,13 @@ public class MediaPlayerApiTest extends ActivityInstrumentationTestCase<MediaFra boolean isSeek = CodecTest.videoSeekTo(MediaNames.VIDEO_H264_AMR); assertTrue("H264AMR SeekTo", isSeek); } - + @LargeTest - public void testVideoWMVSeekTo() throws Exception { - Log.v(TAG, "wmv not enable"); - if (isWMVEnable) { - Log.v(TAG, "wmv enable"); - boolean isSeek = CodecTest.videoSeekTo(MediaNames.VIDEO_WMV); - assertTrue("WMV SeekTo", isSeek); - } + public void testVideoWebmSeekTo() throws Exception { + boolean isSeek = CodecTest.videoSeekTo(MediaNames.VIDEO_WEBM); + assertTrue("WEBM SeekTo", isSeek); } - + @LargeTest public void testSoundRecord() throws Exception { boolean isRecordered = CodecTest.mediaRecorderRecord(MediaNames.RECORDER_OUTPUT); @@ -412,7 +358,7 @@ public class MediaPlayerApiTest extends ActivityInstrumentationTestCase<MediaFra @LargeTest public void testGetThumbnail() throws Exception { - boolean getThumbnail = CodecTest.getThumbnail(MediaNames.VIDEO_H264_AAC, MediaNames.GOLDEN_THUMBNAIL_OUTPUT_2); + boolean getThumbnail = CodecTest.getThumbnail(MediaNames.VIDEO_H264_AAC, MediaNames.GOLDEN_THUMBNAIL_OUTPUT); assertTrue("Get Thumbnail", getThumbnail); } diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java index 3b5b9a3..b396223 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java @@ -356,26 +356,6 @@ public class MediaPlayerPerformance extends ActivityInstrumentationTestCase2<Med assertTrue("H264 playback memory test", memoryResult); } - // Test case 3: Capture the memory usage after each 20 WMV playback - @LargeTest - public void testWMVVideoPlaybackMemoryUsage() throws Exception { - boolean memoryResult = false; - if (MediaProfileReader.getWMVEnable()){ - mStartPid = getMediaserverPid(); - File wmvMemoryOut = new File(MEDIA_MEMORY_OUTPUT); - Writer output = new BufferedWriter(new FileWriter(wmvMemoryOut, true)); - output.write("WMV video playback only\n"); - for (int i = 0; i < NUM_STRESS_LOOP; i++) { - mediaStressPlayback(MediaNames.VIDEO_WMV); - getMemoryWriteToLog(output, i); - } - output.write("\n"); - memoryResult = validateMemoryResult(mStartPid, mStartMemory, output, DECODER_LIMIT); - output.close(); - assertTrue("wmv playback memory test", memoryResult); - } - } - // Test case 4: Capture the memory usage after every 20 video only recorded @LargeTest public void testH263RecordVideoOnlyMemoryUsage() throws Exception { diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java index a66db05..8eb75f3 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java @@ -76,29 +76,29 @@ public class MediaMetadataRetrieverTest extends AndroidTestCase { boolean hasFailed = false; Log.v(TAG, "Thumbnail processing starts"); long startedAt = System.currentTimeMillis(); - for(int i = 0, n = MediaNames.THUMBNAIL_CAPTURE_TEST_FILES.length; i < n; ++i) { + for(int i = 0, n = MediaNames.THUMBNAIL_METADATA_TEST_FILES.length; i < n; ++i) { try { - Log.v(TAG, "File " + i + ": " + MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i]); - if ((MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i].endsWith(".wma") && !supportWMA) || - (MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i].endsWith(".wmv") && !supportWMV) + Log.v(TAG, "File " + i + ": " + MediaNames.THUMBNAIL_METADATA_TEST_FILES[i]); + if ((MediaNames.THUMBNAIL_METADATA_TEST_FILES[i].endsWith(".wma") && !supportWMA) || + (MediaNames.THUMBNAIL_METADATA_TEST_FILES[i].endsWith(".wmv") && !supportWMV) ) { Log.v(TAG, "windows media is not supported and thus we will skip the test for this file"); continue; } - retriever.setDataSource(MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i]); + retriever.setDataSource(MediaNames.THUMBNAIL_METADATA_TEST_FILES[i]); Bitmap bitmap = retriever.getFrameAtTime(-1); assertTrue(bitmap != null); try { - java.io.OutputStream stream = new FileOutputStream(MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i] + ".jpg"); + java.io.OutputStream stream = new FileOutputStream(MediaNames.THUMBNAIL_METADATA_TEST_FILES[i] + ".jpg"); bitmap.compress(Bitmap.CompressFormat.JPEG, 75, stream); stream.close(); } catch (Exception e) { - Log.e(TAG, "Fails to convert the bitmap to a JPEG file for " + MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i]); + Log.e(TAG, "Fails to convert the bitmap to a JPEG file for " + MediaNames.THUMBNAIL_METADATA_TEST_FILES[i]); hasFailed = true; Log.e(TAG, e.toString()); } } catch(Exception e) { - Log.e(TAG, "Fails to setDataSource for file " + MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i]); + Log.e(TAG, "Fails to setDataSource for file " + MediaNames.THUMBNAIL_METADATA_TEST_FILES[i]); hasFailed = true; } Thread.yield(); // Don't be evil @@ -106,7 +106,7 @@ public class MediaMetadataRetrieverTest extends AndroidTestCase { long endedAt = System.currentTimeMillis(); retriever.release(); assertTrue(!hasFailed); - Log.v(TAG, "Average processing time per thumbnail: " + (endedAt - startedAt)/MediaNames.THUMBNAIL_CAPTURE_TEST_FILES.length + " ms"); + Log.v(TAG, "Average processing time per thumbnail: " + (endedAt - startedAt)/MediaNames.THUMBNAIL_METADATA_TEST_FILES.length + " ms"); } @LargeTest @@ -115,19 +115,19 @@ public class MediaMetadataRetrieverTest extends AndroidTestCase { boolean supportWMV = MediaProfileReader.getWMVEnable(); boolean hasFailed = false; MediaMetadataRetriever retriever = new MediaMetadataRetriever(); - for(int i = 0, n = MediaNames.METADATA_RETRIEVAL_TEST_FILES.length; i < n; ++i) { + for(int i = 0, n = MediaNames.THUMBNAIL_METADATA_TEST_FILES.length; i < n; ++i) { try { - Log.v(TAG, "File " + i + ": " + MediaNames.METADATA_RETRIEVAL_TEST_FILES[i]); - if ((MediaNames.METADATA_RETRIEVAL_TEST_FILES[i].endsWith(".wma") && !supportWMA) || - (MediaNames.METADATA_RETRIEVAL_TEST_FILES[i].endsWith(".wmv") && !supportWMV) + Log.v(TAG, "File " + i + ": " + MediaNames.THUMBNAIL_METADATA_TEST_FILES[i]); + if ((MediaNames.THUMBNAIL_METADATA_TEST_FILES[i].endsWith(".wma") && !supportWMA) || + (MediaNames.THUMBNAIL_METADATA_TEST_FILES[i].endsWith(".wmv") && !supportWMV) ) { Log.v(TAG, "windows media is not supported and thus we will skip the test for this file"); continue; } - retriever.setDataSource(MediaNames.METADATA_RETRIEVAL_TEST_FILES[i]); + retriever.setDataSource(MediaNames.THUMBNAIL_METADATA_TEST_FILES[i]); extractAllSupportedMetadataValues(retriever); } catch(Exception e) { - Log.e(TAG, "Fails to setDataSource for file " + MediaNames.METADATA_RETRIEVAL_TEST_FILES[i]); + Log.e(TAG, "Fails to setDataSource for file " + MediaNames.THUMBNAIL_METADATA_TEST_FILES[i]); hasFailed = true; } Thread.yield(); // Don't be evil @@ -239,45 +239,6 @@ public class MediaMetadataRetrieverTest extends AndroidTestCase { assertTrue(!hasFailed); } - @MediumTest - public static void testIntendedUsage() { - // By default, capture frame and retrieve metadata - MediaMetadataRetriever retriever = new MediaMetadataRetriever(); - boolean hasFailed = false; - retriever.setDataSource(MediaNames.TEST_PATH_1); - assertTrue(retriever.getFrameAtTime(-1) != null); - assertTrue(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS) != null); - - // Do not capture frame or retrieve metadata - retriever.setDataSource(MediaNames.TEST_PATH_1); - if (retriever.getFrameAtTime(-1) != null) { - Log.e(TAG, "No frame expected, but is available"); - hasFailed = true; - } - if (retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS) != null) { - Log.e(TAG, "No num track metadata expected, but is available"); - hasFailed = true; - } - - // Capture frame only - retriever.setDataSource(MediaNames.TEST_PATH_1); - assertTrue(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS) == null); - - // Retriever metadata only - retriever.setDataSource(MediaNames.TEST_PATH_1); - if (retriever.getFrameAtTime(-1) != null) { - Log.e(TAG, "No frame expected, but is available"); - hasFailed = true; - } - - // Capture frame and retrieve metadata - retriever.setDataSource(MediaNames.TEST_PATH_1); - assertTrue(retriever.getFrameAtTime(-1) != null); - assertTrue(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS) != null); - retriever.release(); - assertTrue(!hasFailed); - } - // TODO: // Encode and test for the correct mix of metadata elements on a per-file basis? // We should be able to compare the actual returned metadata with the expected metadata diff --git a/media/tests/contents/media_api/goldenThumbnail.png b/media/tests/contents/media_api/goldenThumbnail.png Binary files differnew file mode 100755 index 0000000..3bb6ed2 --- /dev/null +++ b/media/tests/contents/media_api/goldenThumbnail.png diff --git a/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17.mp3 b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17.mp3 Binary files differnew file mode 100755 index 0000000..e0d6a17 --- /dev/null +++ b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17.mp3 diff --git a/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ABR.mp3 b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ABR.mp3 Binary files differnew file mode 100644 index 0000000..12f7193 --- /dev/null +++ b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ABR.mp3 diff --git a/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_CBR.mp3 b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_CBR.mp3 Binary files differnew file mode 100644 index 0000000..12f7193 --- /dev/null +++ b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_CBR.mp3 diff --git a/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V1.mp3 b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V1.mp3 Binary files differnew file mode 100644 index 0000000..29d332b --- /dev/null +++ b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V1.mp3 diff --git a/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V1_ID3V2.mp3 b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V1_ID3V2.mp3 Binary files differnew file mode 100644 index 0000000..ea52638 --- /dev/null +++ b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V1_ID3V2.mp3 diff --git a/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V2.mp3 b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V2.mp3 Binary files differnew file mode 100644 index 0000000..024039c --- /dev/null +++ b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V2.mp3 diff --git a/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_VBR.mp3 b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_VBR.mp3 Binary files differnew file mode 100644 index 0000000..12f7193 --- /dev/null +++ b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_VBR.mp3 diff --git a/media/tests/contents/media_api/music/SHORTMP3.mp3 b/media/tests/contents/media_api/music/SHORTMP3.mp3 Binary files differnew file mode 100755 index 0000000..8b51b5d --- /dev/null +++ b/media/tests/contents/media_api/music/SHORTMP3.mp3 diff --git a/media/tests/contents/media_api/music/ants.mid b/media/tests/contents/media_api/music/ants.mid Binary files differnew file mode 100755 index 0000000..d4ead53 --- /dev/null +++ b/media/tests/contents/media_api/music/ants.mid diff --git a/media/tests/contents/media_api/music/bzk_chic.wav b/media/tests/contents/media_api/music/bzk_chic.wav Binary files differnew file mode 100755 index 0000000..bab1a6b --- /dev/null +++ b/media/tests/contents/media_api/music/bzk_chic.wav diff --git a/media/tests/contents/media_api/music/sine_200+1000Hz_44K_mo.wav b/media/tests/contents/media_api/music/sine_200+1000Hz_44K_mo.wav Binary files differnew file mode 100755 index 0000000..312b6fb --- /dev/null +++ b/media/tests/contents/media_api/music/sine_200+1000Hz_44K_mo.wav diff --git a/media/tests/contents/media_api/music/test_amr_ietf.amr b/media/tests/contents/media_api/music/test_amr_ietf.amr Binary files differnew file mode 100755 index 0000000..540794c --- /dev/null +++ b/media/tests/contents/media_api/music/test_amr_ietf.amr diff --git a/media/tests/contents/media_api/video/big-buck-bunny_trailer.webm b/media/tests/contents/media_api/video/big-buck-bunny_trailer.webm Binary files differnew file mode 100755 index 0000000..6a17395 --- /dev/null +++ b/media/tests/contents/media_api/video/big-buck-bunny_trailer.webm diff --git a/opengl/java/com/google/android/gles_jni/EGLImpl.java b/opengl/java/com/google/android/gles_jni/EGLImpl.java index f162d40..51d6ca8 100644 --- a/opengl/java/com/google/android/gles_jni/EGLImpl.java +++ b/opengl/java/com/google/android/gles_jni/EGLImpl.java @@ -85,7 +85,7 @@ public class EGLImpl implements EGL10 { eglSurfaceId = _eglCreateWindowSurface(display, config, sur, attrib_list); } else if (native_window instanceof SurfaceTexture) { eglSurfaceId = _eglCreateWindowSurfaceTexture(display, config, - ((SurfaceTexture) native_window).mSurfaceTexture, attrib_list); + (SurfaceTexture) native_window, attrib_list); } else { throw new java.lang.UnsupportedOperationException( "eglCreateWindowSurface() can only be called with an instance of " + @@ -143,7 +143,7 @@ public class EGLImpl implements EGL10 { private native int _eglCreatePbufferSurface(EGLDisplay display, EGLConfig config, int[] attrib_list); private native void _eglCreatePixmapSurface(EGLSurface sur, EGLDisplay display, EGLConfig config, Object native_pixmap, int[] attrib_list); private native int _eglCreateWindowSurface(EGLDisplay display, EGLConfig config, Object native_window, int[] attrib_list); - private native int _eglCreateWindowSurfaceTexture(EGLDisplay display, EGLConfig config, int native_window, int[] attrib_list); + private native int _eglCreateWindowSurfaceTexture(EGLDisplay display, EGLConfig config, Object native_window, int[] attrib_list); private native int _eglGetDisplay(Object native_display); private native int _eglGetCurrentContext(); private native int _eglGetCurrentDisplay(); diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index bbe146d..55f5280 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -33,13 +33,6 @@ android:excludeFromRecents="true"> </activity> - <activity android:name=".recent.RecentApplicationsActivity" - android:theme="@android:style/Theme.NoTitleBar" - android:excludeFromRecents="true" - android:launchMode="singleInstance" - android:exported="true"> - </activity> - <!-- started from UsbDeviceSettingsManager --> <activity android:name=".usb.UsbConfirmActivity" android:exported="true" diff --git a/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg.png b/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg.png Binary files differindex 87a67c9..23aabce 100644 --- a/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg.png +++ b/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg.png diff --git a/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_press.png b/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_press.png Binary files differnew file mode 100644 index 0000000..0b0765b --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_press.png diff --git a/packages/SystemUI/res/drawable-large-hdpi/app_icon.png b/packages/SystemUI/res/drawable-large-hdpi/app_icon.png Binary files differdeleted file mode 100644 index aedf7e7..0000000 --- a/packages/SystemUI/res/drawable-large-hdpi/app_icon.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-large-hdpi/recents_bg_protect_tile.png b/packages/SystemUI/res/drawable-large-hdpi/recents_bg_protect_tile.png Binary files differdeleted file mode 100644 index a57c27a..0000000 --- a/packages/SystemUI/res/drawable-large-hdpi/recents_bg_protect_tile.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-large-mdpi/app_icon.png b/packages/SystemUI/res/drawable-large-mdpi/app_icon.png Binary files differdeleted file mode 100644 index 50a8ac8..0000000 --- a/packages/SystemUI/res/drawable-large-mdpi/app_icon.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-large-mdpi/recents_bg_protect_tile.png b/packages/SystemUI/res/drawable-large-mdpi/recents_bg_protect_tile.png Binary files differdeleted file mode 100644 index 87c7be6..0000000 --- a/packages/SystemUI/res/drawable-large-mdpi/recents_bg_protect_tile.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-large-mdpi/recents_blue_glow.9.png b/packages/SystemUI/res/drawable-large-mdpi/recents_blue_glow.9.png Binary files differdeleted file mode 100644 index 4f4ae78..0000000 --- a/packages/SystemUI/res/drawable-large-mdpi/recents_blue_glow.9.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-large-mdpi/recents_callout_line.png b/packages/SystemUI/res/drawable-large-mdpi/recents_callout_line.png Binary files differdeleted file mode 100644 index 5f4c035..0000000 --- a/packages/SystemUI/res/drawable-large-mdpi/recents_callout_line.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-large-mdpi/recents_thumbnail_bg.png b/packages/SystemUI/res/drawable-large-mdpi/recents_thumbnail_bg.png Binary files differdeleted file mode 100644 index 87a67c9..0000000 --- a/packages/SystemUI/res/drawable-large-mdpi/recents_thumbnail_bg.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-large-mdpi/recents_thumbnail_bg_press.png b/packages/SystemUI/res/drawable-large-mdpi/recents_thumbnail_bg_press.png Binary files differdeleted file mode 100644 index a1c39e6..0000000 --- a/packages/SystemUI/res/drawable-large-mdpi/recents_thumbnail_bg_press.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg.png b/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg.png Binary files differindex 87a67c9..23aabce 100644 --- a/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg.png +++ b/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg.png diff --git a/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_press.png b/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_press.png Binary files differindex a1c39e6..0b0765b 100644 --- a/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_press.png +++ b/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_press.png diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/app_icon.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/app_icon.png Binary files differdeleted file mode 100644 index aedf7e7..0000000 --- a/packages/SystemUI/res/drawable-sw600dp-hdpi/app_icon.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/app_icon.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/app_icon.png Binary files differdeleted file mode 100644 index 50a8ac8..0000000 --- a/packages/SystemUI/res/drawable-sw600dp-mdpi/app_icon.png +++ /dev/null diff --git a/packages/SystemUI/res/layout-land/status_bar_recent_item.xml b/packages/SystemUI/res/layout-land/status_bar_recent_item.xml index ce72f04..be4f1d7 100644 --- a/packages/SystemUI/res/layout-land/status_bar_recent_item.xml +++ b/packages/SystemUI/res/layout-land/status_bar_recent_item.xml @@ -39,8 +39,8 @@ android:layout_height="wrap_content" android:layout_alignLeft="@id/app_thumbnail" android:layout_alignTop="@id/app_thumbnail" - android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_border_width" - android:layout_marginTop="@dimen/status_bar_recents_thumbnail_border_height" + android:layout_marginTop="@dimen/status_bar_recents_app_icon_top_margin" + android:layout_marginLeft="@dimen/status_bar_recents_app_icon_left_margin" android:maxWidth="@dimen/status_bar_recents_thumbnail_max_width" android:maxHeight="@dimen/status_bar_recents_thumbnail_max_height" android:adjustViewBounds="true" @@ -56,7 +56,7 @@ android:layout_alignLeft="@id/app_thumbnail" android:layout_below="@id/app_thumbnail" android:layout_marginTop="@dimen/status_bar_recents_text_description_padding" - android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_border_width" + android:layout_marginLeft="@dimen/recents_thumbnail_bg_padding_left" android:singleLine="true" android:ellipsize="marquee" /> @@ -71,7 +71,7 @@ android:layout_alignLeft="@id/app_thumbnail" android:layout_below="@id/app_label" android:layout_marginTop="@dimen/status_bar_recents_text_description_padding" - android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_border_width" + android:layout_marginLeft="@dimen/recents_thumbnail_bg_padding_left" android:singleLine="true" android:ellipsize="marquee" /> diff --git a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml index 75f5ee4..4a80489 100644 --- a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml +++ b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml @@ -27,10 +27,9 @@ <FrameLayout android:id="@+id/recents_bg_protect" android:background="@drawable/recents_bg_protect_tile" - android:layout_width="wrap_content" + android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentBottom="true" - android:layout_alignParentRight="true" android:paddingBottom="@*android:dimen/status_bar_height" android:clipToPadding="false" android:clipChildren="false"> diff --git a/packages/SystemUI/res/layout/status_bar_recent_item.xml b/packages/SystemUI/res/layout-port/status_bar_recent_item.xml index cd42d7e..76965c9 100644 --- a/packages/SystemUI/res/layout/status_bar_recent_item.xml +++ b/packages/SystemUI/res/layout-port/status_bar_recent_item.xml @@ -36,53 +36,52 @@ <ImageView android:id="@+id/app_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_alignParentLeft="true" - android:layout_alignParentTop="true" - android:layout_marginLeft="131dip" - android:layout_marginTop="13dip" + android:layout_alignLeft="@id/app_thumbnail" + android:layout_alignTop="@id/app_thumbnail" + android:layout_marginLeft="@dimen/status_bar_recents_app_icon_left_margin" + android:layout_marginTop="@dimen/status_bar_recents_app_icon_top_margin" android:maxWidth="@dimen/status_bar_recents_thumbnail_max_width" android:maxHeight="@dimen/status_bar_recents_thumbnail_max_height" android:adjustViewBounds="true" /> - <View android:id="@+id/recents_callout_line" - android:layout_width="97dip" - android:layout_height="1dip" - android:layout_alignParentTop="true" - android:layout_marginTop="61dip" - android:layout_alignParentLeft="true" - android:layout_marginLeft="16dip" - android:layout_toLeftOf="@id/app_thumbnail" - android:layout_marginRight="3dip" - android:background="@drawable/recents_callout_line" - /> - <TextView android:id="@+id/app_label" - android:layout_width="97dip" + android:layout_width="@dimen/status_bar_recents_app_label_width" android:layout_height="wrap_content" - android:textSize="@dimen/status_bar_recents_app_description_text_size" + android:textSize="@dimen/status_bar_recents_app_label_text_size" android:fadingEdge="horizontal" android:fadingEdgeLength="@dimen/status_bar_recents_fading_edge_length" android:scrollHorizontally="true" android:layout_alignParentLeft="true" - android:layout_alignParentTop="true" - android:layout_marginLeft="16dip" - android:layout_marginTop="32dip" + android:layout_alignTop="@id/app_icon" + android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin" android:singleLine="true" android:ellipsize="marquee" /> + <View android:id="@+id/recents_callout_line" + android:layout_width="@dimen/status_bar_recents_app_label_width" + android:layout_height="1dip" + android:layout_alignParentLeft="true" + android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin" + android:layout_toLeftOf="@id/app_thumbnail" + android:layout_below="@id/app_label" + android:layout_marginRight="3dip" + android:layout_marginTop="3dip" + android:background="@drawable/recents_callout_line" + /> + <TextView android:id="@+id/app_description" - android:layout_width="97dip" + android:layout_width="@dimen/status_bar_recents_app_label_width" android:layout_height="wrap_content" android:textSize="@dimen/status_bar_recents_app_description_text_size" android:fadingEdge="horizontal" android:fadingEdgeLength="@dimen/status_bar_recents_fading_edge_length" android:scrollHorizontally="true" android:layout_alignParentLeft="true" - android:layout_alignParentTop="true" - android:layout_marginLeft="16dip" - android:layout_marginTop="61dip" + android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin" + android:layout_below="@id/recents_callout_line" + android:layout_marginTop="3dip" android:singleLine="true" android:ellipsize="marquee" /> diff --git a/packages/SystemUI/res/layout/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml index 703cbc1..9391f9d 100644 --- a/packages/SystemUI/res/layout/status_bar_recent_panel.xml +++ b/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml @@ -22,12 +22,12 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/recents_root" android:layout_height="match_parent" - android:layout_width="wrap_content"> + android:layout_width="match_parent"> <FrameLayout android:id="@+id/recents_bg_protect" android:background="@drawable/recents_bg_protect_tile" - android:layout_width="wrap_content" + android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentBottom="true" android:paddingBottom="@*android:dimen/status_bar_height" @@ -35,9 +35,9 @@ android:clipChildren="false"> <LinearLayout android:id="@+id/recents_glow" - android:layout_width="wrap_content" + android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginBottom="-49dip" + android:layout_marginBottom="0dp" android:layout_gravity="bottom" android:background="@drawable/recents_blue_glow" android:orientation="horizontal" @@ -47,7 +47,7 @@ <com.android.systemui.recent.RecentsVerticalScrollView android:id="@+id/recents_container" android:layout_width="@dimen/status_bar_recents_width" android:layout_height="wrap_content" - android:layout_marginRight="@dimen/status_bar_recents_right_glow_margin" + android:layout_marginRight="0dp" android:divider="@null" android:stackFromBottom="true" android:fadingEdge="vertical" diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_row.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_notification_row.xml deleted file mode 100644 index 93085d7..0000000 --- a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_row.xml +++ /dev/null @@ -1,45 +0,0 @@ -<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="@dimen/notification_height" - > - - <ImageButton - android:id="@+id/veto" - android:layout_width="48dp" - android:layout_height="match_parent" - android:layout_centerVertical="true" - android:layout_alignParentRight="true" - android:src="@drawable/status_bar_veto" - android:scaleType="center" - android:background="@null" - android:paddingRight="8dp" - android:paddingLeft="8dp" - /> - - <ImageView - android:id="@+id/large_icon" - android:layout_width="@android:dimen/notification_large_icon_width" - android:layout_height="@android:dimen/notification_large_icon_height" - android:layout_alignParentTop="true" - android:layout_alignParentLeft="true" - android:scaleType="center" - /> - - <com.android.systemui.statusbar.LatestItemView android:id="@+id/content" - android:layout_width="match_parent" - android:layout_height="64dp" - android:layout_alignParentTop="true" - android:layout_toRightOf="@id/large_icon" - android:layout_toLeftOf="@id/veto" - android:focusable="true" - android:clickable="true" - /> - - <View - android:layout_width="match_parent" - android:layout_height="1dp" - android:layout_alignParentBottom="true" - android:background="@android:drawable/divider_horizontal_dark" - /> - -</RelativeLayout> diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml index cd42d7e..9687866 100644 --- a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml +++ b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml @@ -36,53 +36,53 @@ <ImageView android:id="@+id/app_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_alignParentLeft="true" - android:layout_alignParentTop="true" - android:layout_marginLeft="131dip" - android:layout_marginTop="13dip" + android:layout_alignLeft="@id/app_thumbnail" + android:layout_alignTop="@id/app_thumbnail" + android:layout_marginLeft="@dimen/status_bar_recents_app_icon_left_margin" + android:layout_marginTop="@dimen/status_bar_recents_app_icon_top_margin" android:maxWidth="@dimen/status_bar_recents_thumbnail_max_width" android:maxHeight="@dimen/status_bar_recents_thumbnail_max_height" android:adjustViewBounds="true" /> - <View android:id="@+id/recents_callout_line" - android:layout_width="97dip" - android:layout_height="1dip" - android:layout_alignParentTop="true" - android:layout_marginTop="61dip" - android:layout_alignParentLeft="true" - android:layout_marginLeft="16dip" - android:layout_toLeftOf="@id/app_thumbnail" - android:layout_marginRight="3dip" - android:background="@drawable/recents_callout_line" - /> - <TextView android:id="@+id/app_label" - android:layout_width="97dip" + android:layout_width="@dimen/status_bar_recents_app_label_width" android:layout_height="wrap_content" - android:textSize="@dimen/status_bar_recents_app_description_text_size" + android:textSize="@dimen/status_bar_recents_app_label_text_size" android:fadingEdge="horizontal" android:fadingEdgeLength="@dimen/status_bar_recents_fading_edge_length" android:scrollHorizontally="true" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" - android:layout_marginLeft="16dip" + android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin" android:layout_marginTop="32dip" android:singleLine="true" android:ellipsize="marquee" /> + <View android:id="@+id/recents_callout_line" + android:layout_width="@dimen/status_bar_recents_app_label_width" + android:layout_height="1dip" + android:layout_below="@id/app_label" + android:layout_marginTop="3dip" + android:layout_alignParentLeft="true" + android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin" + android:layout_toLeftOf="@id/app_thumbnail" + android:layout_marginRight="3dip" + android:background="@drawable/recents_callout_line" + /> + <TextView android:id="@+id/app_description" - android:layout_width="97dip" + android:layout_width="@dimen/status_bar_recents_app_label_width" android:layout_height="wrap_content" android:textSize="@dimen/status_bar_recents_app_description_text_size" android:fadingEdge="horizontal" android:fadingEdgeLength="@dimen/status_bar_recents_fading_edge_length" android:scrollHorizontally="true" android:layout_alignParentLeft="true" - android:layout_alignParentTop="true" - android:layout_marginLeft="16dip" - android:layout_marginTop="61dip" + android:layout_below="@id/recents_callout_line" + android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin" + android:layout_marginTop="3dip" android:singleLine="true" android:ellipsize="marquee" /> diff --git a/packages/SystemUI/res/layout/recent_apps_activity.xml b/packages/SystemUI/res/layout/recent_apps_activity.xml deleted file mode 100644 index ec661e8..0000000 --- a/packages/SystemUI/res/layout/recent_apps_activity.xml +++ /dev/null @@ -1,55 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** Copyright 2008, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> - -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical"> - - <!-- Title --> - <TextView - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:gravity="center" - android:textAppearance="?android:attr/textAppearanceSmall" - android:textColor="#80FFFFFF" - android:textStyle="bold" - android:singleLine="true" - android:text="@string/recent_tasks_title" - android:visibility="gone"/> - - <!-- This is only intended to be visible when carousel is invisible --> - <TextView - android:id="@+id/no_applications_message" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:textAppearance="?android:attr/textAppearanceSmall" - android:text="@string/recent_tasks_empty" - android:visibility="gone"/> - - <com.android.systemui.recent.RecentApplicationsCarouselView - android:id="@+id/carousel" - android:layout_width="match_parent" - android:layout_height="0dip" - android:layout_weight="1"> - </com.android.systemui.recent.RecentApplicationsCarouselView> - -</LinearLayout> diff --git a/packages/SystemUI/res/layout/recents_detail_view.xml b/packages/SystemUI/res/layout/recents_detail_view.xml deleted file mode 100644 index 879d0f2..0000000 --- a/packages/SystemUI/res/layout/recents_detail_view.xml +++ /dev/null @@ -1,40 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** Copyright 2008, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> - -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical"> - - <!-- Application Title --> - <TextView android:id="@+id/app_title" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:textAppearance="?android:attr/textAppearanceMedium" - android:singleLine="true"/> - - <!-- Application Details --> - <TextView - android:id="@+id/app_description" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:textAppearance="?android:attr/textAppearanceSmall"/> - -</LinearLayout> diff --git a/packages/SystemUI/res/layout/status_bar_notification_row.xml b/packages/SystemUI/res/layout/status_bar_notification_row.xml index 93085d7..aff6a6e 100644 --- a/packages/SystemUI/res/layout/status_bar_notification_row.xml +++ b/packages/SystemUI/res/layout/status_bar_notification_row.xml @@ -9,6 +9,7 @@ android:layout_height="match_parent" android:layout_centerVertical="true" android:layout_alignParentRight="true" + android:layout_marginRight="-80dp" android:src="@drawable/status_bar_veto" android:scaleType="center" android:background="@null" @@ -30,7 +31,7 @@ android:layout_height="64dp" android:layout_alignParentTop="true" android:layout_toRightOf="@id/large_icon" - android:layout_toLeftOf="@id/veto" + android:layout_alignParentRight="true" android:focusable="true" android:clickable="true" /> diff --git a/packages/SystemUI/res/values-hdpi/dimens.xml b/packages/SystemUI/res/values-hdpi/dimens.xml new file mode 100644 index 0000000..741b75a --- /dev/null +++ b/packages/SystemUI/res/values-hdpi/dimens.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + * Copyright (c) 2011, 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. +*/ +--> +<resources> + <!-- Offsets for rendering thumbnails over drawable recents_thumbnail_bg --> + <dimen name="recents_thumbnail_bg_padding_left">6px</dimen> + <dimen name="recents_thumbnail_bg_padding_top">7px</dimen> + <dimen name="recents_thumbnail_bg_padding_right">6px</dimen> + <dimen name="recents_thumbnail_bg_padding_bottom">6px</dimen> +</resources> diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml index 6f1453e..0219a77 100644 --- a/packages/SystemUI/res/values-land/dimens.xml +++ b/packages/SystemUI/res/values-land/dimens.xml @@ -23,15 +23,17 @@ <!-- Width of a recent app view, including all content --> <dimen name="status_bar_recents_thumbnail_view_width">156dp</dimen> <!-- How far the thumbnail for a recent app appears from left edge --> - <dimen name="status_bar_recents_thumbnail_left_margin">0dp</dimen> + <dimen name="status_bar_recents_thumbnail_left_margin">8dp</dimen> + <!-- How far the thumbnail for a recent app appears from top edge --> + <dimen name="status_bar_recents_thumbnail_top_margin">12dp</dimen> <!-- Width of scrollable area in recents --> <dimen name="status_bar_recents_width">128dp</dimen> - <!-- Thumbnail border width --> - <dimen name="status_bar_recents_thumbnail_border_width">8dp</dimen> - <!-- Thumbnail border height --> - <dimen name="status_bar_recents_thumbnail_border_height">12dp</dimen> <!-- Padding for text descriptions --> <dimen name="status_bar_recents_text_description_padding">8dp</dimen> + <!-- Width of application label text --> + <dimen name="status_bar_recents_app_label_width">97dip</dimen> + <!-- Left margin of application label text --> + <dimen name="status_bar_recents_app_label_left_margin">16dip</dimen> <!-- Margin between recents container and glow on the right --> <dimen name="status_bar_recents_right_glow_margin">0dip</dimen> </resources> diff --git a/packages/SystemUI/res/values-large/dimens.xml b/packages/SystemUI/res/values-large/dimens.xml index f8a4a1c..9d89e21 100644 --- a/packages/SystemUI/res/values-large/dimens.xml +++ b/packages/SystemUI/res/values-large/dimens.xml @@ -22,32 +22,6 @@ <dimen name="status_bar_panel_bottom_offset">36dp</dimen> <!-- gap on either side of status bar notification icons --> <dimen name="status_bar_icon_padding">8dp</dimen> - - <!-- Recent Applications parameters --> - <!-- Width of a recent app view, including all content --> - <dimen name="status_bar_recents_thumbnail_view_width">156dp</dimen> - <!-- How far the thumbnail for a recent app appears from left edge --> - <dimen name="status_bar_recents_thumbnail_left_margin">110dp</dimen> - <!-- Upper width limit for application icon --> - <dimen name="status_bar_recents_thumbnail_max_width">64dp</dimen> - <!-- Upper height limit for application icon --> - <dimen name="status_bar_recents_thumbnail_max_height">64dp</dimen> - <!-- Width of scrollable area in recents --> - <dimen name="status_bar_recents_width">356dp</dimen> - <!-- Thumbnail border width --> - <dimen name="status_bar_recents_thumbnail_border_width">12dp</dimen> - <!-- Thumbnail border height --> - <dimen name="status_bar_recents_thumbnail_border_height">12dp</dimen> - <!-- Padding for text descriptions --> - <dimen name="status_bar_recents_text_description_padding">8dp</dimen> - <!-- Size of application label text --> - <dimen name="status_bar_recents_app_label_text_size">18dip</dimen> - <!-- Size of application description text --> - <dimen name="status_bar_recents_app_description_text_size">18dip</dimen> - <!-- Size of fading edge for scroll effect --> - <dimen name="status_bar_recents_fading_edge_length">20dip</dimen> - <!-- Margin between recents container and glow on the right --> - <dimen name="status_bar_recents_right_glow_margin">100dip</dimen> </resources> diff --git a/packages/SystemUI/res/values-mdpi/dimens.xml b/packages/SystemUI/res/values-mdpi/dimens.xml new file mode 100644 index 0000000..741b75a --- /dev/null +++ b/packages/SystemUI/res/values-mdpi/dimens.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + * Copyright (c) 2011, 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. +*/ +--> +<resources> + <!-- Offsets for rendering thumbnails over drawable recents_thumbnail_bg --> + <dimen name="recents_thumbnail_bg_padding_left">6px</dimen> + <dimen name="recents_thumbnail_bg_padding_top">7px</dimen> + <dimen name="recents_thumbnail_bg_padding_right">6px</dimen> + <dimen name="recents_thumbnail_bg_padding_bottom">6px</dimen> +</resources> diff --git a/packages/SystemUI/res/values-port/dimens.xml b/packages/SystemUI/res/values-port/dimens.xml new file mode 100644 index 0000000..54c25fa --- /dev/null +++ b/packages/SystemUI/res/values-port/dimens.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + * Copyright (c) 2006, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ +--> +<resources> + <!-- Recent Applications parameters --> + <!-- Width of a recent app view, including all content --> + <dimen name="status_bar_recents_thumbnail_view_width">156dp</dimen> + <!-- How far the thumbnail for a recent app appears from left edge --> + <dimen name="status_bar_recents_thumbnail_left_margin">110dp</dimen> + <!-- Width of scrollable area in recents --> + <dimen name="status_bar_recents_width">356dp</dimen> + <!-- Padding for text descriptions --> + <dimen name="status_bar_recents_text_description_padding">8dp</dimen> + <!-- Width of application label text --> + <dimen name="status_bar_recents_app_label_width">97dip</dimen> + <!-- Left margin of application label text --> + <dimen name="status_bar_recents_app_label_left_margin">16dip</dimen> + <!-- Margin between recents container and glow on the right --> + <dimen name="status_bar_recents_right_glow_margin">100dip</dimen> +</resources> diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml index 944e0ee..b4fd8ab 100644 --- a/packages/SystemUI/res/values-sw600dp/dimens.xml +++ b/packages/SystemUI/res/values-sw600dp/dimens.xml @@ -28,4 +28,40 @@ <dimen name="notification_panel_min_height">770dp</dimen> <!-- Bottom margin (from display edge) for status bar panels --> <dimen name="panel_float">56dp</dimen> + + <!-- Recent Applications parameters --> + <!-- Width of a recent app view, including all content --> + <dimen name="status_bar_recents_thumbnail_view_width">156dp</dimen> + <!-- How far the thumbnail for a recent app appears from left edge --> + <dimen name="status_bar_recents_thumbnail_left_margin">110dp</dimen> + <!-- Upper width limit for application icon --> + <dimen name="status_bar_recents_thumbnail_max_width">64dp</dimen> + <!-- Upper height limit for application icon --> + <dimen name="status_bar_recents_thumbnail_max_height">64dp</dimen> + <!-- Width of scrollable area in recents --> + <dimen name="status_bar_recents_width">356dp</dimen> + <!-- Padding for text descriptions --> + <dimen name="status_bar_recents_text_description_padding">8dp</dimen> + <!-- Size of application label text --> + <dimen name="status_bar_recents_app_label_text_size">18dip</dimen> + <!-- Size of application description text --> + <dimen name="status_bar_recents_app_description_text_size">18dip</dimen> + <!-- Width of application label text --> + <dimen name="status_bar_recents_app_label_width">97dip</dimen> + <!-- Left margin for application label --> + <dimen name="status_bar_recents_app_label_left_margin">16dip</dimen> + <!-- Size of fading edge for scroll effect --> + <dimen name="status_bar_recents_fading_edge_length">20dip</dimen> + <!-- Margin between recents container and glow on the right --> + <dimen name="status_bar_recents_right_glow_margin">100dip</dimen> + + <!-- Offsets for rendering thumbnails over drawable recents_thumbnail_bg --> + <dimen name="recents_thumbnail_bg_padding_left">15px</dimen> + <dimen name="recents_thumbnail_bg_padding_top">8px</dimen> + <dimen name="recents_thumbnail_bg_padding_right">12px</dimen> + <dimen name="recents_thumbnail_bg_padding_bottom">8px</dimen> + + <!-- Where to place the app icon over the thumbnail --> + <dimen name="status_bar_recents_app_icon_left_margin">13dp</dimen> + <dimen name="status_bar_recents_app_icon_top_margin">13dp</dimen> </resources> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 83eaaa8..fc35a48 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -20,22 +20,14 @@ <dimen name="status_bar_edge_ignore">5dp</dimen> <!-- Recent Applications parameters --> - <!-- Width of a recent app view, including all content --> - <dimen name="status_bar_recents_thumbnail_view_width">156dp</dimen> - <!-- How far the thumbnail for a recent app appears from left edge --> - <dimen name="status_bar_recents_thumbnail_left_margin">110dp</dimen> <!-- Upper width limit for application icon --> <dimen name="status_bar_recents_thumbnail_max_width">64dp</dimen> <!-- Upper height limit for application icon --> <dimen name="status_bar_recents_thumbnail_max_height">64dp</dimen> - <!-- Width of scrollable area in recents --> - <dimen name="status_bar_recents_width">356dp</dimen> - <!-- Thumbnail border width --> - <dimen name="status_bar_recents_thumbnail_border_width">12dp</dimen> - <!-- Thumbnail border height --> - <dimen name="status_bar_recents_thumbnail_border_height">12dp</dimen> - <!-- Padding for text descriptions --> - <dimen name="status_bar_recents_text_description_padding">8dp</dimen> + <!-- Where to place the app icon over the thumbnail --> + <dimen name="status_bar_recents_app_icon_left_margin">13dp</dimen> + <dimen name="status_bar_recents_app_icon_top_margin">13dp</dimen> + <!-- Size of application label text --> <dimen name="status_bar_recents_app_label_text_size">18dip</dimen> <!-- Size of application description text --> diff --git a/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java b/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java index b876075..49a65d8 100644 --- a/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java +++ b/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java @@ -36,14 +36,16 @@ import android.view.View; View mScrimView; View mContentView; AnimatorSet mContentAnim; + Animator.AnimatorListener mListener; // the panel will start to appear this many px from the end final int HYPERSPACE_OFFRAMP = 200; - public Choreographer(View root, View scrim, View content) { + public Choreographer(View root, View scrim, View content, Animator.AnimatorListener listener) { mRootView = root; mScrimView = scrim; mContentView = content; + mListener = listener; } void createAnimation(boolean appearing) { @@ -86,6 +88,9 @@ import android.view.View; .with(posAnim); mContentAnim.setDuration(appearing ? OPEN_DURATION : CLOSE_DURATION); mContentAnim.addListener(this); + if (mListener != null) { + mContentAnim.addListener(mListener); + } } void startAnimation(boolean appearing) { diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java index 194c9d1..3dbcc59 100644 --- a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java +++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java @@ -16,7 +16,7 @@ package com.android.systemui.recent; -import com.android.systemui.recent.RecentsPanelView.ActvityDescriptionAdapter; +import com.android.systemui.recent.RecentsPanelView.ActivityDescriptionAdapter; import android.animation.Animator; import android.animation.Animator.AnimatorListener; @@ -49,7 +49,7 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView private static final float THRESHHOLD = 50; private static final boolean DEBUG_INVALIDATE = false; private LinearLayout mLinearLayout; - private ActvityDescriptionAdapter mAdapter; + private ActivityDescriptionAdapter mAdapter; private RecentsCallback mCallback; protected int mLastScrollPosition; private View mCurrentView; @@ -273,7 +273,7 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView } } - public void setAdapter(ActvityDescriptionAdapter adapter) { + public void setAdapter(ActivityDescriptionAdapter adapter) { mAdapter = adapter; mAdapter.registerDataSetObserver(new DataSetObserver() { public void onChanged() { diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java index e2b3446..b8dc63d 100644 --- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java @@ -19,6 +19,7 @@ package com.android.systemui.recent; import java.util.ArrayList; import java.util.List; +import android.animation.Animator; import android.animation.LayoutTransition; import android.app.ActivityManager; import android.content.Context; @@ -52,27 +53,33 @@ import android.widget.RelativeLayout; import android.widget.TextView; import com.android.systemui.R; +import com.android.systemui.statusbar.StatusBar; +import com.android.systemui.statusbar.phone.PhoneStatusBar; import com.android.systemui.statusbar.tablet.StatusBarPanel; import com.android.systemui.statusbar.tablet.TabletStatusBar; public class RecentsPanelView extends RelativeLayout - implements OnItemClickListener, RecentsCallback, StatusBarPanel { - private static final int GLOW_PADDING = 15; + implements OnItemClickListener, RecentsCallback, StatusBarPanel, Animator.AnimatorListener { static final String TAG = "RecentsListView"; - static final boolean DEBUG = TabletStatusBar.DEBUG; + static final boolean DEBUG = TabletStatusBar.DEBUG || PhoneStatusBar.DEBUG; private static final int DISPLAY_TASKS = 20; private static final int MAX_TASKS = DISPLAY_TASKS + 1; // allow extra for non-apps - private TabletStatusBar mBar; + private StatusBar mBar; private ArrayList<ActivityDescription> mActivityDescriptions; private int mIconDpi; private View mRecentsScrim; private View mRecentsGlowView; private View mRecentsContainer; private Bitmap mGlowBitmap; + // TODO: add these widgets attributes to the layout file + private int mGlowBitmapPaddingLeftPx; + private int mGlowBitmapPaddingTopPx; + private int mGlowBitmapPaddingRightPx; + private int mGlowBitmapPaddingBottomPx; private boolean mShowing; private Choreographer mChoreo; private View mRecentsDismissButton; - private ActvityDescriptionAdapter mListAdapter; + private ActivityDescriptionAdapter mListAdapter; /* package */ final static class ActivityDescription { int taskId; // application task id for curating apps @@ -108,10 +115,10 @@ public class RecentsPanelView extends RelativeLayout ActivityDescription activityDescription; } - /* package */ final class ActvityDescriptionAdapter extends BaseAdapter { + /* package */ final class ActivityDescriptionAdapter extends BaseAdapter { private LayoutInflater mInflater; - public ActvityDescriptionAdapter(Context context) { + public ActivityDescriptionAdapter(Context context) { mInflater = LayoutInflater.from(context); } @@ -183,6 +190,26 @@ public class RecentsPanelView extends RelativeLayout } } + public void onAnimationCancel(Animator animation) { + } + + public void onAnimationEnd(Animator animation) { + if (mShowing) { + final LayoutTransition transitioner = new LayoutTransition(); + ((ViewGroup)mRecentsContainer).setLayoutTransition(transitioner); + createCustomAnimations(transitioner); + } else { + ((ViewGroup)mRecentsContainer).setLayoutTransition(null); + } + } + + public void onAnimationRepeat(Animator animation) { + } + + public void onAnimationStart(Animator animation) { + } + + /** * We need to be aligned at the bottom. LinearLayout can't do this, so instead, * let LinearLayout do all the hard work, and then shift everything down to the bottom. @@ -201,7 +228,7 @@ public class RecentsPanelView extends RelativeLayout return mShowing; } - public void setBar(TabletStatusBar bar) { + public void setBar(StatusBar bar) { mBar = bar; } @@ -217,7 +244,16 @@ public class RecentsPanelView extends RelativeLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE; mIconDpi = xlarge ? DisplayMetrics.DENSITY_HIGH : res.getDisplayMetrics().densityDpi; + mGlowBitmap = BitmapFactory.decodeResource(res, R.drawable.recents_thumbnail_bg); + mGlowBitmapPaddingLeftPx = + res.getDimensionPixelSize(R.dimen.recents_thumbnail_bg_padding_left); + mGlowBitmapPaddingTopPx = + res.getDimensionPixelSize(R.dimen.recents_thumbnail_bg_padding_top); + mGlowBitmapPaddingRightPx = + res.getDimensionPixelSize(R.dimen.recents_thumbnail_bg_padding_right); + mGlowBitmapPaddingBottomPx = + res.getDimensionPixelSize(R.dimen.recents_thumbnail_bg_padding_bottom); } @Override @@ -225,7 +261,7 @@ public class RecentsPanelView extends RelativeLayout super.onFinishInflate(); mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); mRecentsContainer = findViewById(R.id.recents_container); - mListAdapter = new ActvityDescriptionAdapter(mContext); + mListAdapter = new ActivityDescriptionAdapter(mContext); if (mRecentsContainer instanceof RecentsListView) { RecentsListView listView = (RecentsListView) mRecentsContainer; listView.setAdapter(mListAdapter); @@ -246,13 +282,10 @@ public class RecentsPanelView extends RelativeLayout throw new IllegalArgumentException("missing RecentsListView/RecentsScrollView"); } - final LayoutTransition transitioner = new LayoutTransition(); - ((ViewGroup)mRecentsContainer).setLayoutTransition(transitioner); - createCustomAnimations(transitioner); mRecentsGlowView = findViewById(R.id.recents_glow); mRecentsScrim = (View) findViewById(R.id.recents_bg_protect); - mChoreo = new Choreographer(this, mRecentsScrim, mRecentsGlowView); + mChoreo = new Choreographer(this, mRecentsScrim, mRecentsGlowView, this); mRecentsDismissButton = findViewById(R.id.recents_dismiss_button); mRecentsDismissButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { @@ -402,10 +435,9 @@ public class RecentsPanelView extends RelativeLayout Log.v(TAG, "Source thumb: " + srcWidth + "x" + srcHeight); canvas.drawBitmap(thumbnail, new Rect(0, 0, srcWidth-1, srcHeight-1), - new RectF(GLOW_PADDING, - GLOW_PADDING - 7.0f, - outBitmap.getWidth() - GLOW_PADDING + 3.0f, - outBitmap.getHeight() - GLOW_PADDING + 7.0f), paint); + new RectF(mGlowBitmapPaddingLeftPx, mGlowBitmapPaddingTopPx, + outBitmap.getWidth() - mGlowBitmapPaddingRightPx, + outBitmap.getHeight() - mGlowBitmapPaddingBottomPx), paint); } return outBitmap; } diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java index 54ec6b5..6a962cb 100644 --- a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java +++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java @@ -16,7 +16,7 @@ package com.android.systemui.recent; -import com.android.systemui.recent.RecentsPanelView.ActvityDescriptionAdapter; +import com.android.systemui.recent.RecentsPanelView.ActivityDescriptionAdapter; import android.animation.Animator; import android.animation.Animator.AnimatorListener; @@ -49,7 +49,7 @@ public class RecentsVerticalScrollView extends ScrollView private static final float THRESHHOLD = 50; private static final boolean DEBUG_INVALIDATE = false; private LinearLayout mLinearLayout; - private ActvityDescriptionAdapter mAdapter; + private ActivityDescriptionAdapter mAdapter; private RecentsCallback mCallback; protected int mLastScrollPosition; private View mCurrentView; @@ -275,7 +275,7 @@ public class RecentsVerticalScrollView extends ScrollView } } - public void setAdapter(ActvityDescriptionAdapter adapter) { + public void setAdapter(ActivityDescriptionAdapter adapter) { mAdapter = adapter; mAdapter.registerDataSetObserver(new DataSetObserver() { public void onChanged() { diff --git a/packages/SystemUI/src/com/android/systemui/recent/carousel/RecentApplicationsActivity.java b/packages/SystemUI/src/com/android/systemui/recent/carousel/RecentApplicationsActivity.java deleted file mode 100644 index 45e230f..0000000 --- a/packages/SystemUI/src/com/android/systemui/recent/carousel/RecentApplicationsActivity.java +++ /dev/null @@ -1,532 +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.systemui.recent.carousel; - -import com.android.systemui.R; - -import com.android.ex.carousel.CarouselView; -import com.android.ex.carousel.CarouselViewHelper; -import com.android.ex.carousel.CarouselRS.CarouselCallback; -import com.android.ex.carousel.CarouselViewHelper.DetailTextureParameters; - -import java.util.ArrayList; -import java.util.List; - -import android.app.Activity; -import android.app.ActivityManager; -import android.app.ActivityManagerNative; -import android.app.IActivityManager; -import android.app.IThumbnailReceiver; -import android.app.ActivityManager.RunningTaskInfo; -import android.content.ActivityNotFoundException; -import android.content.Context; -import android.content.Intent; -import android.content.pm.ActivityInfo; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Canvas; -import android.graphics.Matrix; -import android.graphics.Paint; -import android.graphics.PaintFlagsDrawFilter; -import android.graphics.PorterDuffXfermode; -import android.graphics.PorterDuff; -import android.graphics.Bitmap.Config; -import android.graphics.drawable.Drawable; -import android.graphics.PixelFormat; -import android.os.Bundle; -import android.os.RemoteException; -import android.util.Log; -import android.view.View; -import android.view.View.MeasureSpec; -import android.widget.TextView; - -public class RecentApplicationsActivity extends Activity { - private static final String TAG = "RecentApplicationsActivity"; - private static boolean DBG = false; - private static final int CARD_SLOTS = 56; - private static final int VISIBLE_SLOTS = 7; - private static final int MAX_TASKS = VISIBLE_SLOTS * 2; - - // TODO: these should be configurable - private static final int DETAIL_TEXTURE_MAX_WIDTH = 200; - private static final int DETAIL_TEXTURE_MAX_HEIGHT = 80; - private static final int TEXTURE_WIDTH = 256; - private static final int TEXTURE_HEIGHT = 256; - - private ActivityManager mActivityManager; - private List<RunningTaskInfo> mRunningTaskList; - private boolean mPortraitMode = true; - private ArrayList<ActivityDescription> mActivityDescriptions - = new ArrayList<ActivityDescription>(); - private CarouselView mCarouselView; - private LocalCarouselViewHelper mHelper; - private View mNoRecentsView; - private Bitmap mLoadingBitmap; - private Bitmap mRecentOverlay; - private boolean mHidden = false; - private boolean mHiding = false; - private DetailInfo mDetailInfo; - - /** - * This class is a container for all items associated with the DetailView we'll - * be drawing to a bitmap and sending to Carousel. - * - */ - static final class DetailInfo { - public DetailInfo(View _view, TextView _title, TextView _desc) { - view = _view; - title = _title; - description = _desc; - } - - /** - * Draws view into the given bitmap, if provided - * @param bitmap - */ - public Bitmap draw(Bitmap bitmap) { - resizeView(view, DETAIL_TEXTURE_MAX_WIDTH, DETAIL_TEXTURE_MAX_HEIGHT); - int desiredWidth = view.getWidth(); - int desiredHeight = view.getHeight(); - if (bitmap == null || desiredWidth != bitmap.getWidth() - || desiredHeight != bitmap.getHeight()) { - bitmap = Bitmap.createBitmap(desiredWidth, desiredHeight, Config.ARGB_8888); - } - Canvas canvas = new Canvas(bitmap); - view.draw(canvas); - return bitmap; - } - - /** - * Force a layout pass on the given view. - */ - private void resizeView(View view, int maxWidth, int maxHeight) { - int widthSpec = MeasureSpec.getMode(MeasureSpec.AT_MOST) - | MeasureSpec.getSize(maxWidth); - int heightSpec = MeasureSpec.getMode(MeasureSpec.AT_MOST) - | MeasureSpec.getSize(maxHeight); - view.measure(widthSpec, heightSpec); - view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight()); - Log.v(TAG, "RESIZED VIEW: " + view.getWidth() + ", " + view.getHeight()); - } - - public View view; - public TextView title; - public TextView description; - } - - static class ActivityDescription { - int id; - Bitmap thumbnail; // generated by Activity.onCreateThumbnail() - Drawable icon; // application package icon - String label; // application package label - CharSequence description; // generated by Activity.onCreateDescription() - Intent intent; // launch intent for application - Matrix matrix; // arbitrary rotation matrix to correct orientation - int position; // position in list - - public ActivityDescription(Bitmap _thumbnail, - Drawable _icon, String _label, String _desc, int _id, int _pos) - { - thumbnail = _thumbnail; - icon = _icon; - label = _label; - description = _desc; - id = _id; - position = _pos; - } - - public void clear() { - icon = null; - thumbnail = null; - label = null; - description = null; - intent = null; - matrix = null; - id = -1; - position = -1; - } - }; - - private ActivityDescription findActivityDescription(int id) { - for (int i = 0; i < mActivityDescriptions.size(); i++) { - ActivityDescription item = mActivityDescriptions.get(i); - if (item != null && item.id == id) { - return item; - } - } - return null; - } - - private class LocalCarouselViewHelper extends CarouselViewHelper { - private DetailTextureParameters mDetailParams = new DetailTextureParameters(10.0f, 20.0f); - - public LocalCarouselViewHelper(Context context) { - super(context); - } - - @Override - public DetailTextureParameters getDetailTextureParameters(int id) { - return mDetailParams; - } - - public void onCardSelected(int n) { - if (n < mActivityDescriptions.size()) { - ActivityDescription item = mActivityDescriptions.get(n); - if (item.id >= 0) { - // This is an active task; it should just go to the foreground. - final ActivityManager am = (ActivityManager) - getSystemService(Context.ACTIVITY_SERVICE); - am.moveTaskToFront(item.id, ActivityManager.MOVE_TASK_WITH_HOME); - } else if (item.intent != null) { - // prepare a launch intent and send it - item.intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY - | Intent.FLAG_ACTIVITY_TASK_ON_HOME); - try { - if (DBG) Log.v(TAG, "Starting intent " + item.intent); - startActivity(item.intent); - overridePendingTransition(R.anim.recent_app_enter, R.anim.recent_app_leave); - } catch (ActivityNotFoundException e) { - if (DBG) Log.w("Recent", "Unable to launch recent task", e); - } - finish(); - } - } - } - - @Override - public Bitmap getTexture(final int id) { - if (DBG) Log.v(TAG, "onRequestTexture(" + id + ")"); - ActivityDescription info; - synchronized(mActivityDescriptions) { - info = mActivityDescriptions.get(id); - } - Bitmap bitmap = null; - if (info != null) { - bitmap = compositeBitmap(info); - } - return bitmap; - } - - @Override - public Bitmap getDetailTexture(int n) { - Bitmap bitmap = null; - if (n < mActivityDescriptions.size()) { - ActivityDescription item = mActivityDescriptions.get(n); - mDetailInfo.title.setText(item.label); - mDetailInfo.description.setText(item.description); - bitmap = mDetailInfo.draw(null); - } - return bitmap; - } - }; - - private Bitmap compositeBitmap(ActivityDescription info) { - final int targetWidth = TEXTURE_WIDTH; - final int targetHeight = TEXTURE_HEIGHT; - final int border = 3; // inset along the edge for thumnnail content - final int overlap = 1; // how many pixels of overlap between border and thumbnail - final Resources res = getResources(); - if (mRecentOverlay == null) { - mRecentOverlay = BitmapFactory.decodeResource(res, R.drawable.recent_overlay); - } - - // Create a bitmap of the proper size/format and set the canvas to draw to it - final Bitmap result = Bitmap.createBitmap(targetWidth, targetHeight, Bitmap.Config.ARGB_8888); - final Canvas canvas = new Canvas(result); - canvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG, Paint.FILTER_BITMAP_FLAG)); - Paint paint = new Paint(); - paint.setFilterBitmap(false); - - paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC)); - canvas.save(); - if (info.thumbnail != null) { - // Draw the thumbnail - int sourceWidth = targetWidth - 2 * (border - overlap); - int sourceHeight = targetHeight - 2 * (border - overlap); - final float scaleX = (float) sourceWidth / info.thumbnail.getWidth(); - final float scaleY = (float) sourceHeight / info.thumbnail.getHeight(); - canvas.translate(border * 0.5f, border * 0.5f); - canvas.scale(scaleX, scaleY); - canvas.drawBitmap(info.thumbnail, 0, 0, paint); - } else { - // Draw the Loading bitmap placeholder, TODO: Remove when RS handles blending - final float scaleX = (float) targetWidth / mLoadingBitmap.getWidth(); - final float scaleY = (float) targetHeight / mLoadingBitmap.getHeight(); - canvas.scale(scaleX, scaleY); - canvas.drawBitmap(mLoadingBitmap, 0, 0, paint); - } - canvas.restore(); - - // Draw overlay - canvas.save(); - final float scaleOverlayX = (float) targetWidth / mRecentOverlay.getWidth(); - final float scaleOverlayY = (float) targetHeight / mRecentOverlay.getHeight(); - canvas.scale(scaleOverlayX, scaleOverlayY); - paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.ADD)); - canvas.drawBitmap(mRecentOverlay, 0, 0, paint); - canvas.restore(); - - // Draw icon - if (info.icon != null) { - canvas.save(); - info.icon.draw(canvas); - canvas.restore(); - } - - return result; - } - - private final IThumbnailReceiver mThumbnailReceiver = new IThumbnailReceiver.Stub() { - - public void finished() throws RemoteException { - - } - - public void newThumbnail(final int id, final Bitmap bitmap, CharSequence description) - throws RemoteException { - int w = bitmap.getWidth(); - int h = bitmap.getHeight(); - if (DBG) Log.v(TAG, "New thumbnail for id=" + id + ", dimensions=" + w + "x" + h - + " description '" + description + "'"); - ActivityDescription info = findActivityDescription(id); - if (info != null) { - info.thumbnail = bitmap; - info.description = description; - final int thumbWidth = bitmap.getWidth(); - final int thumbHeight = bitmap.getHeight(); - if ((mPortraitMode && thumbWidth > thumbHeight) - || (!mPortraitMode && thumbWidth < thumbHeight)) { - Matrix matrix = new Matrix(); - matrix.setRotate(90.0f, (float) thumbWidth / 2, (float) thumbHeight / 2); - info.matrix = matrix; - } else { - info.matrix = null; - } - // Force Carousel to request new textures for this item. - mCarouselView.setTextureForItem(info.position, null); - mCarouselView.setDetailTextureForItem(info.position, 0, 0, 0, 0, null); - } else { - if (DBG) Log.v(TAG, "Can't find view for id " + id); - } - } - }; - - /** - * We never really finish() RecentApplicationsActivity, since we don't want to - * get destroyed and pay the start-up cost to restart it. - */ - @Override - public void finish() { - moveTaskToBack(true); - } - - @Override - protected void onNewIntent(Intent intent) { - mHidden = !mHidden; - if (mHidden) { - mHiding = true; - moveTaskToBack(true); - } else { - mHiding = false; - } - super.onNewIntent(intent); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - final Resources res = getResources(); - final View decorView = getWindow().getDecorView(); - - getWindow().getDecorView().setBackgroundColor(0x80000000); - - if (mCarouselView == null) { - long t = System.currentTimeMillis(); - setContentView(R.layout.recent_apps_activity); - long elapsed = System.currentTimeMillis() - t; - Log.v(TAG, "Recents layout took " + elapsed + "ms to load"); - mLoadingBitmap = BitmapFactory.decodeResource(res, R.drawable.recent_rez_border); - mCarouselView = (CarouselView)findViewById(R.id.carousel); - mHelper = new LocalCarouselViewHelper(this); - mHelper.setCarouselView(mCarouselView); - - mCarouselView.setSlotCount(CARD_SLOTS); - mCarouselView.setVisibleSlots(VISIBLE_SLOTS); - mCarouselView.createCards(0); - mCarouselView.setStartAngle((float) -(2.0f*Math.PI * 5 / CARD_SLOTS)); - mCarouselView.setDefaultBitmap(mLoadingBitmap); - mCarouselView.setLoadingBitmap(mLoadingBitmap); - mCarouselView.setRezInCardCount(3.0f); - mCarouselView.getHolder().setFormat(PixelFormat.TRANSLUCENT); - - mNoRecentsView = (View) findViewById(R.id.no_applications_message); - - mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); - mPortraitMode = decorView.getHeight() > decorView.getWidth(); - - // Load detail view which will be used to render text - View detail = getLayoutInflater().inflate(R.layout.recents_detail_view, null); - TextView title = (TextView) detail.findViewById(R.id.app_title); - TextView description = (TextView) detail.findViewById(R.id.app_description); - mDetailInfo = new DetailInfo(detail, title, description); - - refresh(); - } - } - - @Override - protected void onResume() { - super.onResume(); - refresh(); - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - mPortraitMode = newConfig.orientation == Configuration.ORIENTATION_PORTRAIT; - if (DBG) Log.v(TAG, "CONFIG CHANGE, mPortraitMode = " + mPortraitMode); - refresh(); - } - - void updateRunningTasks() { - mRunningTaskList = mActivityManager.getRunningTasks(MAX_TASKS, - 0, mThumbnailReceiver); - if (DBG) Log.v(TAG, "Portrait: " + mPortraitMode); - for (RunningTaskInfo r : mRunningTaskList) { - if (r.thumbnail != null) { - int thumbWidth = r.thumbnail.getWidth(); - int thumbHeight = r.thumbnail.getHeight(); - if (DBG) Log.v(TAG, "Got thumbnail " + thumbWidth + "x" + thumbHeight); - ActivityDescription desc = findActivityDescription(r.id); - if (desc != null) { - desc.thumbnail = r.thumbnail; - desc.description = r.description; - if ((mPortraitMode && thumbWidth > thumbHeight) - || (!mPortraitMode && thumbWidth < thumbHeight)) { - Matrix matrix = new Matrix(); - matrix.setRotate(90.0f, (float) thumbWidth / 2, (float) thumbHeight / 2); - desc.matrix = matrix; - } - } else { - if (DBG) Log.v(TAG, "Couldn't find ActivityDesc for id=" + r.id); - } - } else { - if (DBG) Log.v(TAG, "*** RUNNING THUMBNAIL WAS NULL ***"); - } - } - } - - private void updateRecentTasks() { - final PackageManager pm = getPackageManager(); - final ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); - - final List<ActivityManager.RecentTaskInfo> recentTasks = - am.getRecentTasks(MAX_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE); - - ActivityInfo homeInfo = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME) - .resolveActivityInfo(pm, 0); - - // IconUtilities iconUtilities = new IconUtilities(this); // FIXME - - int numTasks = recentTasks.size(); - mActivityDescriptions.clear(); - for (int i = 0, index = 0; i < numTasks && (index < MAX_TASKS); ++i) { - final ActivityManager.RecentTaskInfo recentInfo = recentTasks.get(i); - - Intent intent = new Intent(recentInfo.baseIntent); - if (recentInfo.origActivity != null) { - intent.setComponent(recentInfo.origActivity); - } - - // Skip the current home activity. - if (homeInfo != null - && homeInfo.packageName.equals(intent.getComponent().getPackageName()) - && homeInfo.name.equals(intent.getComponent().getClassName())) { - continue; - } - - intent.setFlags((intent.getFlags()&~Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) - | Intent.FLAG_ACTIVITY_NEW_TASK); - final ResolveInfo resolveInfo = pm.resolveActivity(intent, 0); - if (resolveInfo != null) { - final ActivityInfo info = resolveInfo.activityInfo; - final String title = info.loadLabel(pm).toString(); - Drawable icon = info.loadIcon(pm); - - int id = recentTasks.get(i).id; - if (id != -1 && title != null && title.length() > 0 && icon != null) { - // icon = null; FIXME: iconUtilities.createIconDrawable(icon); - ActivityDescription item = new ActivityDescription( - null, icon, title, null, id, index); - item.intent = intent; - mActivityDescriptions.add(item); - if (DBG) Log.v(TAG, "Added item[" + index - + "], id=" + item.id - + ", title=" + item.label); - ++index; - } else { - if (DBG) Log.v(TAG, "SKIPPING item " + id); - } - } - } - } - - private final Runnable mRefreshRunnable = new Runnable() { - public void run() { - updateRecentTasks(); - updateRunningTasks(); - showCarousel(mActivityDescriptions.size() > 0); - } - }; - - private void showCarousel(boolean show) { - if (show) { - mCarouselView.createCards(mActivityDescriptions.size()); - for (int i = 1; i < mActivityDescriptions.size(); i++) { - // Force Carousel to update textures. Note we don't do this for the first item, - // since it will be updated when mThumbnailReceiver returns a thumbnail. - // TODO: only do this for apps that have changed. - mCarouselView.setTextureForItem(i, null); - mCarouselView.setDetailTextureForItem(i, 0, 0, 0, 0, null); - } - // Make carousel visible - mNoRecentsView.setVisibility(View.GONE); - mCarouselView.setVisibility(View.VISIBLE); - mCarouselView.createCards(mActivityDescriptions.size()); - } else { - // show "No Recent Tasks" - mNoRecentsView.setVisibility(View.VISIBLE); - mCarouselView.setVisibility(View.GONE); - } - } - - private void refresh() { - if (!mHiding && mCarouselView != null) { - // Don't update the view now. Instead, post a request so it happens next time - // we reach the looper after a delay. This way we can fold multiple refreshes - // into just the latest. - mCarouselView.removeCallbacks(mRefreshRunnable); - mCarouselView.postDelayed(mRefreshRunnable, 50); - } - } -} diff --git a/packages/SystemUI/src/com/android/systemui/recent/carousel/RecentApplicationsCarouselView.java b/packages/SystemUI/src/com/android/systemui/recent/carousel/RecentApplicationsCarouselView.java deleted file mode 100644 index 1afb086..0000000 --- a/packages/SystemUI/src/com/android/systemui/recent/carousel/RecentApplicationsCarouselView.java +++ /dev/null @@ -1,39 +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.systemui.recent.carousel; - -import android.content.Context; -import android.util.AttributeSet; - -import com.android.ex.carousel.CarouselView; -import com.android.systemui.R; - -public class RecentApplicationsCarouselView extends CarouselView { - - public RecentApplicationsCarouselView(Context context) { - this(context, null); - } - - public RecentApplicationsCarouselView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public Info getRenderScriptInfo() { - return new Info(R.raw.carousel); - } - -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java index f81820e..62d7500 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java @@ -61,6 +61,7 @@ public class CommandQueue extends IStatusBar.Stub { private static final int MSG_SET_HARD_KEYBOARD_STATUS = 10 << MSG_SHIFT; private static final int MSG_USER_ACTIVITY = 11 << MSG_SHIFT; + private static final int MSG_TOGGLE_RECENT_APPS = 12 << MSG_SHIFT; private StatusBarIconList mList; private Callbacks mCallbacks; @@ -90,6 +91,7 @@ public class CommandQueue extends IStatusBar.Stub { public void setImeWindowStatus(IBinder token, int vis, int backDisposition); public void setHardKeyboardStatus(boolean available, boolean enabled); public void userActivity(); + public void toggleRecentApps(); } public CommandQueue(Callbacks callbacks, StatusBarIconList list) { @@ -196,6 +198,13 @@ public class CommandQueue extends IStatusBar.Stub { } } + public void toggleRecentApps() { + synchronized (mList) { + mHandler.removeMessages(MSG_TOGGLE_RECENT_APPS); + mHandler.obtainMessage(MSG_TOGGLE_RECENT_APPS, 0, 0, null).sendToTarget(); + } + } + private final class H extends Handler { public void handleMessage(Message msg) { final int what = msg.what & MSG_MASK; @@ -265,6 +274,9 @@ public class CommandQueue extends IStatusBar.Stub { case MSG_USER_ACTIVITY: mCallbacks.userActivity(); break; + case MSG_TOGGLE_RECENT_APPS: + mCallbacks.toggleRecentApps(); + break; } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java index e567dc7..ca75138 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java @@ -53,6 +53,7 @@ public abstract class StatusBar extends SystemUI implements CommandQueue.Callbac protected abstract View makeStatusBarView(); protected abstract int getStatusBarGravity(); public abstract int getStatusBarHeight(); + public abstract void animateCollapse(); private DoNotDisturb mDoNotDisturb; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java index dbfbe11..d9d9c06 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java @@ -29,6 +29,8 @@ import android.view.View; import android.view.ViewDebug; import android.widget.FrameLayout; +import java.text.NumberFormat; + import com.android.internal.statusbar.StatusBarIcon; import com.android.systemui.R; @@ -180,7 +182,18 @@ public class StatusBarIconView extends AnimatedImageView { } void placeNumber() { - final String str = mNumberText = Integer.toString(mIcon.number); + final String str; + final int tooBig = mContext.getResources().getInteger( + android.R.integer.status_bar_notification_info_maxnum); + if (mIcon.number > tooBig) { + str = mContext.getResources().getString( + android.R.string.status_bar_notification_info_overflow); + } else { + NumberFormat f = NumberFormat.getIntegerInstance(); + str = f.format(mIcon.number); + } + mNumberText = str; + final int w = getWidth(); final int h = getHeight(); final Rect r = new Rect(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index cc8358e..0b82123 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -28,10 +28,12 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.Resources; +import android.content.res.Configuration; import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.net.Uri; +import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.os.Handler; @@ -74,6 +76,7 @@ import com.android.internal.statusbar.StatusBarIconList; import com.android.internal.statusbar.StatusBarNotification; import com.android.systemui.R; +import com.android.systemui.recent.RecentsPanelView; import com.android.systemui.statusbar.NotificationData; import com.android.systemui.statusbar.StatusBar; import com.android.systemui.statusbar.StatusBarIconView; @@ -83,6 +86,7 @@ import com.android.systemui.statusbar.policy.DateView; public class PhoneStatusBar extends StatusBar { static final String TAG = "PhoneStatusBar"; static final boolean SPEW = false; + public static final boolean DEBUG = false; public static final String ACTION_STATUSBAR_START = "com.android.internal.policy.statusbar.START"; @@ -94,6 +98,8 @@ public class PhoneStatusBar extends StatusBar { private static final int MSG_ANIMATE_REVEAL = 1001; private static final int MSG_SHOW_INTRUDER = 1002; private static final int MSG_HIDE_INTRUDER = 1003; + private static final int MSG_OPEN_RECENTS_PANEL = 1020; + private static final int MSG_CLOSE_RECENTS_PANEL = 1021; // will likely move to a resource or other tunable param at some point private static final int INTRUDER_ALERT_DECAY_MS = 10000; @@ -160,6 +166,9 @@ public class PhoneStatusBar extends StatusBar { private View mTickerView; private boolean mTicking; + // Recent applications + private RecentsPanelView mRecentsPanel; + // Tracking finger for opening/closing. int mEdgeBorder; // corresponds to R.dimen.status_bar_edge_ignore boolean mTracking; @@ -296,6 +305,9 @@ public class PhoneStatusBar extends StatusBar { setAreThereNotifications(); mDateView.setVisibility(View.INVISIBLE); + // Recents Panel + initializeRecentsPanel(); + // receive broadcasts IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); @@ -306,6 +318,51 @@ public class PhoneStatusBar extends StatusBar { return sb; } + protected WindowManager.LayoutParams getRecentsLayoutParams() { + boolean translucent = false; + WindowManager.LayoutParams lp = new WindowManager.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT, + WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, + WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN + | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM + | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH + | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, + (translucent ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT)); + lp.gravity = Gravity.BOTTOM | Gravity.LEFT; + lp.setTitle("RecentsPanel"); + lp.windowAnimations = R.style.Animation_RecentPanel; + lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED + | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; + return lp; + } + + protected void initializeRecentsPanel() { + // Recents Panel + boolean visible = false; + if (mRecentsPanel != null) { + visible = mRecentsPanel.getVisibility() == View.VISIBLE; + WindowManagerImpl.getDefault().removeView(mRecentsPanel); + } + mRecentsPanel = (RecentsPanelView) View.inflate(mContext, + R.layout.status_bar_recent_panel, null); + + mRecentsPanel.setOnTouchListener(new TouchOutsideListener(MSG_CLOSE_RECENTS_PANEL, + mRecentsPanel)); + mRecentsPanel.setVisibility(View.GONE); + WindowManager.LayoutParams lp = getRecentsLayoutParams(); + + WindowManagerImpl.getDefault().addView(mRecentsPanel, lp); + mRecentsPanel.setBar(this); + if (visible) { + // need to set visibility to View.GONE earlier since that + // triggers refreshing application list + mRecentsPanel.setVisibility(View.VISIBLE); + mRecentsPanel.show(true, false); + } + + } + protected int getStatusBarGravity() { return Gravity.TOP | Gravity.FILL_HORIZONTAL; } @@ -581,6 +638,12 @@ public class PhoneStatusBar extends StatusBar { } } + @Override + protected void onConfigurationChanged(Configuration newConfig) { + initializeRecentsPanel(); + } + + View[] makeNotificationView(StatusBarNotification notification, ViewGroup parent) { Notification n = notification.notification; RemoteViews remoteViews = n.contentView; @@ -789,6 +852,21 @@ public class PhoneStatusBar extends StatusBar { case MSG_HIDE_INTRUDER: setIntruderAlertVisibility(false); break; + case MSG_OPEN_RECENTS_PANEL: + if (DEBUG) Slog.d(TAG, "opening recents panel"); + if (mRecentsPanel != null) { + disable(StatusBarManager.DISABLE_BACK); + mRecentsPanel.setVisibility(View.VISIBLE); + mRecentsPanel.show(true, true); + } + break; + case MSG_CLOSE_RECENTS_PANEL: + if (DEBUG) Slog.d(TAG, "closing recents panel"); + if (mRecentsPanel != null && mRecentsPanel.isShowing()) { + disable(StatusBarManager.DISABLE_NONE); + mRecentsPanel.show(false, true); + } + break; } } } @@ -835,6 +913,10 @@ public class PhoneStatusBar extends StatusBar { } public void animateCollapse() { + animateCollapse(false); + } + + public void animateCollapse(boolean excludeRecents) { if (SPEW) { Slog.d(TAG, "animateCollapse(): mExpanded=" + mExpanded + " mExpandedVisible=" + mExpandedVisible @@ -844,6 +926,11 @@ public class PhoneStatusBar extends StatusBar { + " mAnimVel=" + mAnimVel); } + if (!excludeRecents) { + mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL); + mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL); + } + if (!mExpandedVisible) { return; } @@ -1557,6 +1644,13 @@ public class PhoneStatusBar extends StatusBar { } catch (RemoteException ex) { } } + public void toggleRecentApps() { + int msg = (mRecentsPanel.getVisibility() == View.GONE) + ? MSG_OPEN_RECENTS_PANEL : MSG_CLOSE_RECENTS_PANEL; + mHandler.removeMessages(msg); + mHandler.sendEmptyMessage(msg); + } + /** * The LEDs are turned o)ff when the notification panel is shown, even just a little bit. * This was added last-minute and is inconsistent with the way the rest of the notifications @@ -1625,7 +1719,14 @@ public class PhoneStatusBar extends StatusBar { String action = intent.getAction(); if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action) || Intent.ACTION_SCREEN_OFF.equals(action)) { - animateCollapse(); + boolean excludeRecents = false; + if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) { + String reason = intent.getExtras().getString("reason"); + if (reason != null) { + excludeRecents = reason.equals("recentapps"); + } + } + animateCollapse(excludeRecents); } else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) { repositionNavigationBar(); @@ -1690,5 +1791,27 @@ public class PhoneStatusBar extends StatusBar { vibrate(); } }; + + public class TouchOutsideListener implements View.OnTouchListener { + private int mMsg; + private RecentsPanelView mPanel; + + public TouchOutsideListener(int msg, RecentsPanelView panel) { + mMsg = msg; + mPanel = panel; + } + + public boolean onTouch(View v, MotionEvent ev) { + final int action = ev.getAction(); + if (action == MotionEvent.ACTION_OUTSIDE + || (action == MotionEvent.ACTION_DOWN + && !mPanel.isInContentArea((int)ev.getX(), (int)ev.getY()))) { + mHandler.removeMessages(mMsg); + mHandler.sendEmptyMessage(mMsg); + return true; + } + return false; + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java index b5ea7b2..981fb24 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java @@ -52,11 +52,16 @@ public class NotificationRowLayout extends ViewGroup { private static final boolean ANIMATE_LAYOUT = true; + private static final boolean CLEAR_IF_SWIPED_FAR_ENOUGH = true; + + private static final boolean CONSTRAIN_SWIPE_ON_PERMANENT = true; + private static final int APPEAR_ANIM_LEN = SLOW_ANIMATIONS ? 5000 : 250; private static final int DISAPPEAR_ANIM_LEN = APPEAR_ANIM_LEN; private static final int SNAP_ANIM_LEN = SLOW_ANIMATIONS ? 1000 : 250; private static final float SWIPE_ESCAPE_VELOCITY = 1500f; + private static final float SWIPE_ANIM_VELOCITY_MIN = 1000f; Rect mTmpRect = new Rect(); int mNumRows = 0; @@ -149,6 +154,21 @@ public class NotificationRowLayout extends ViewGroup { } return mSlidingChild != null; } + + protected boolean canBeCleared(View v) { + final View veto = v.findViewById(R.id.veto); + return (veto != null && veto.getVisibility() != View.GONE); + } + + protected boolean clear(View v) { + final View veto = v.findViewById(R.id.veto); + if (veto != null && veto.getVisibility() != View.GONE) { + veto.performClick(); + return true; + } + return false; + } + @Override public boolean onTouchEvent(MotionEvent ev) { final int action = ev.getAction(); @@ -159,7 +179,13 @@ public class NotificationRowLayout extends ViewGroup { case MotionEvent.ACTION_MOVE: mVT.addMovement(ev); - mSlidingChild.setTranslationX(ev.getX() - mInitialTouchX); + float delta = (ev.getX() - mInitialTouchX); + if (CONSTRAIN_SWIPE_ON_PERMANENT && !canBeCleared(mSlidingChild)) { + delta = Math.copySign( + Math.min(Math.abs(delta), + mSlidingChild.getMeasuredWidth() * 0.2f), delta); + } + mSlidingChild.setTranslationX(delta); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: @@ -168,14 +194,13 @@ public class NotificationRowLayout extends ViewGroup { if (DEBUG) Slog.d(TAG, "exit velocity: " + mVT.getXVelocity()); boolean restore = true; mLiftoffVelocity = mVT.getXVelocity(); - if (Math.abs(mLiftoffVelocity) > SWIPE_ESCAPE_VELOCITY) { - // flingadingy + if (Math.abs(mLiftoffVelocity) > SWIPE_ESCAPE_VELOCITY + || (CLEAR_IF_SWIPED_FAR_ENOUGH && + (mSlidingChild.getTranslationX() * 2) > mSlidingChild.getMeasuredWidth())) + { - View veto = mSlidingChild.findViewById(R.id.veto); - if (veto != null && veto.getVisibility() == View.VISIBLE) { - veto.performClick(); - restore = false; - } + // flingadingy + restore = ! clear(mSlidingChild); } if (restore) { // snappity @@ -230,7 +255,8 @@ public class NotificationRowLayout extends ViewGroup { child.setPivotY(0); final float velocity = (mSlidingChild == child) - ? mLiftoffVelocity : SWIPE_ESCAPE_VELOCITY; + ? Math.min(mLiftoffVelocity, SWIPE_ANIM_VELOCITY_MIN) + : SWIPE_ESCAPE_VELOCITY; final TimeAnimator zoom = new TimeAnimator(); zoom.setTimeListener(new TimeAnimator.TimeListener() { @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java index 937ddc1..93f7af3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java @@ -76,7 +76,6 @@ import com.android.systemui.statusbar.policy.LocationController; import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.statusbar.policy.Prefs; import com.android.systemui.recent.RecentsPanelView; -import com.android.systemui.recent.carousel.RecentApplicationsActivity; public class TabletStatusBar extends StatusBar implements HeightReceiver.OnBarHeightChangedListener, @@ -1173,20 +1172,12 @@ public class TabletStatusBar extends StatusBar implements public void onClickRecentButton() { if (DEBUG) Slog.d(TAG, "clicked recent apps; disabled=" + mDisabled); - if (mRecentsPanel == null) { - Intent intent = new Intent(); - intent.setClass(mContext, RecentApplicationsActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK - | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); - mContext.startActivity(intent); - } else { - if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) { - int msg = (mRecentsPanel.getVisibility() == View.GONE) - ? MSG_OPEN_RECENTS_PANEL - : MSG_CLOSE_RECENTS_PANEL; - mHandler.removeMessages(msg); - mHandler.sendEmptyMessage(msg); - } + if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) { + int msg = (mRecentsPanel.getVisibility() == View.GONE) + ? MSG_OPEN_RECENTS_PANEL + : MSG_CLOSE_RECENTS_PANEL; + mHandler.removeMessages(msg); + mHandler.sendEmptyMessage(msg); } } @@ -1698,6 +1689,13 @@ public class TabletStatusBar extends StatusBar implements public void userActivity() { } + public void toggleRecentApps() { + int msg = (mRecentsPanel.getVisibility() == View.GONE) + ? MSG_OPEN_RECENTS_PANEL : MSG_CLOSE_RECENTS_PANEL; + mHandler.removeMessages(msg); + mHandler.sendEmptyMessage(msg); + } + public class TouchOutsideListener implements View.OnTouchListener { private int mMsg; private StatusBarPanel mPanel; diff --git a/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java b/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java index 8fa6c7a..c54e719 100644 --- a/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java +++ b/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java @@ -23,7 +23,8 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; -import android.net.ConnectivityManager; +import android.net.IConnectivityManager; +import android.os.ServiceManager; import android.util.Log; import android.view.View; import android.widget.Button; @@ -37,7 +38,7 @@ public class ConfirmDialog extends Activity implements CompoundButton.OnCheckedC private String mPackageName; - private ConnectivityManager mService; + private IConnectivityManager mService; private AlertDialog mDialog; private Button mButton; @@ -47,7 +48,9 @@ public class ConfirmDialog extends Activity implements CompoundButton.OnCheckedC super.onResume(); try { mPackageName = getCallingPackage(); - mService = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); + + mService = IConnectivityManager.Stub.asInterface( + ServiceManager.getService(Context.CONNECTIVITY_SERVICE)); if (mPackageName.equals(mService.prepareVpn(null))) { setResult(RESULT_OK); diff --git a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java index 853e625..ba3f344 100644 --- a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java +++ b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java @@ -23,9 +23,10 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; -import android.net.ConnectivityManager; +import android.net.IConnectivityManager; import android.os.Handler; import android.os.Message; +import android.os.ServiceManager; import android.os.SystemClock; import android.util.Log; import android.view.View; @@ -34,45 +35,41 @@ 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 ConnectivityManager mService; + private IConnectivityManager mService; private AlertDialog mDialog; private TextView mDuration; 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 = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); + 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); @@ -82,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(); @@ -110,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(); } } @@ -126,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() { @@ -157,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/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java index 72209f6..f385a23 100644 --- a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java +++ b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java @@ -114,7 +114,15 @@ public class KeyguardUpdateMonitor { } String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE); if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) { - this.simState = IccCard.State.ABSENT; + final String absentReason = intent + .getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON); + + if (IccCard.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals( + absentReason)) { + this.simState = IccCard.State.PERM_DISABLED; + } else { + this.simState = IccCard.State.ABSENT; + } } else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) { this.simState = IccCard.State.READY; } else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) { diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java index 8a60098..8ba235b 100644 --- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java +++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java @@ -580,7 +580,9 @@ public class KeyguardViewMediator implements KeyguardViewCallback, final boolean provisioned = mUpdateMonitor.isDeviceProvisioned(); final IccCard.State state = mUpdateMonitor.getSimState(); final boolean lockedOrMissing = state.isPinLocked() - || ((state == IccCard.State.ABSENT) && requireSim); + || ((state == IccCard.State.ABSENT + || state == IccCard.State.PERM_DISABLED) + && requireSim); if (!lockedOrMissing && !provisioned) { if (DEBUG) Log.d(TAG, "doKeyguard: not showing because device isn't provisioned" @@ -687,12 +689,15 @@ public class KeyguardViewMediator implements KeyguardViewCallback, switch (simState) { case ABSENT: + case PERM_DISABLED: // only force lock screen in case of missing sim if user hasn't // gone through setup wizard if (!mUpdateMonitor.isDeviceProvisioned()) { if (!isShowing()) { - if (DEBUG) Log.d(TAG, "INTENT_VALUE_ICC_ABSENT and keygaurd isn't showing, we need " - + "to show the keyguard since the device isn't provisioned yet."); + if (DEBUG) Log.d(TAG, "INTENT_VALUE_ICC_ABSENT " + + "or PERM_DISABLED and keygaurd isn't showing," + + " we need to show the keyguard since the " + + "device isn't provisioned yet."); doKeyguard(); } else { resetStateLocked(); diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java index 874acd0..eea3040 100644 --- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java +++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java @@ -181,7 +181,8 @@ public class LockPatternKeyguardView extends KeyguardViewBase { private boolean stuckOnLockScreenBecauseSimMissing() { return mRequiresSim && (!mUpdateMonitor.isDeviceProvisioned()) - && (mUpdateMonitor.getSimState() == IccCard.State.ABSENT); + && (mUpdateMonitor.getSimState() == IccCard.State.ABSENT || + mUpdateMonitor.getSimState() == IccCard.State.PERM_DISABLED); } /** diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java index ed5a058..19adb3e 100644 --- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java +++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java @@ -55,8 +55,10 @@ public class LockPatternKeyguardViewProperties implements KeyguardViewProperties private boolean isSimPinSecure() { final IccCard.State simState = mUpdateMonitor.getSimState(); - return (simState == IccCard.State.PIN_REQUIRED || simState == IccCard.State.PUK_REQUIRED - || simState == IccCard.State.ABSENT); + return (simState == IccCard.State.PIN_REQUIRED + || simState == IccCard.State.PUK_REQUIRED + || simState == IccCard.State.ABSENT + || simState == IccCard.State.PERM_DISABLED); } } diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java index 08f9ebb..8b7a61e 100644 --- a/policy/src/com/android/internal/policy/impl/LockScreen.java +++ b/policy/src/com/android/internal/policy/impl/LockScreen.java @@ -129,7 +129,12 @@ class LockScreen extends LinearLayout implements KeyguardScreen, /** * The sim card is locked. */ - SimLocked(true); + SimLocked(true), + + /** + * The sim card is permanently disabled due to puk unlock failure + */ + SimPermDisabled(false); private final boolean mShowStatusLines; @@ -503,7 +508,9 @@ class LockScreen extends LinearLayout implements KeyguardScreen, */ private Status getCurrentStatus(IccCard.State simState) { boolean missingAndNotProvisioned = (!mUpdateMonitor.isDeviceProvisioned() - && simState == IccCard.State.ABSENT); + && (simState == IccCard.State.ABSENT + || simState == IccCard.State.PERM_DISABLED)); + if (missingAndNotProvisioned) { return Status.SimMissingLocked; } @@ -521,6 +528,8 @@ class LockScreen extends LinearLayout implements KeyguardScreen, return Status.SimPukLocked; case READY: return Status.Normal; + case PERM_DISABLED: + return Status.SimPermDisabled; case UNKNOWN: return Status.SimMissing; } @@ -595,6 +604,18 @@ class LockScreen extends LinearLayout implements KeyguardScreen, enableUnlock(); // do not need to show the e-call button; user may unlock break; + case SimPermDisabled: + // text + mStatusView.setCarrierText(R.string.lockscreen_missing_sim_message_short); + mScreenLocked.setText( + R.string.lockscreen_permanent_disabled_sim_instructions); + + // layout + mScreenLocked.setVisibility(View.VISIBLE); + mLockPatternUtils.updateEmergencyCallText(mEmergencyCallText); + enableUnlock(); // do not need to show the e-call button; user may unlock + break; + case SimMissingLocked: // text mStatusView.setCarrierText( diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 5728989..b52e7e1 100755 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -149,10 +149,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { static final int LONG_PRESS_POWER_NOTHING = 0; static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1; static final int LONG_PRESS_POWER_SHUT_OFF = 2; - + + // These need to match the documentation/constant in + // core/res/res/values/config.xml static final int LONG_PRESS_HOME_NOTHING = 0; static final int LONG_PRESS_HOME_RECENT_DIALOG = 1; - static final int LONG_PRESS_HOME_RECENT_ACTIVITY = 2; + static final int LONG_PRESS_HOME_RECENT_SYSTEM_UI = 2; // wallpaper is at the bottom, though the window manager may move it. static final int WALLPAPER_LAYER = 2; @@ -623,7 +625,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { mLongPressOnHomeBehavior = mContext.getResources().getInteger(R.integer.config_longPressOnHomeBehavior); if (mLongPressOnHomeBehavior < LONG_PRESS_HOME_NOTHING || - mLongPressOnHomeBehavior > LONG_PRESS_HOME_RECENT_ACTIVITY) { + mLongPressOnHomeBehavior > LONG_PRESS_HOME_RECENT_SYSTEM_UI) { mLongPressOnHomeBehavior = LONG_PRESS_HOME_NOTHING; } } @@ -639,17 +641,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_DIALOG) { showOrHideRecentAppsDialog(0, true /*dismissIfShown*/); - } else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_ACTIVITY) { + } else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_SYSTEM_UI) { try { - Intent intent = new Intent(); - intent.setClassName("com.android.systemui", - "com.android.systemui.recent.RecentApplicationsActivity"); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK - | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); - mContext.startActivity(intent); - return; - } catch (ActivityNotFoundException e) { - Log.e(TAG, "Failed to launch RecentAppsIntent", e); + mStatusBarService.toggleRecentApps(); + } catch (RemoteException e) { + Slog.e(TAG, "RemoteException when showing recent apps", e); } } } diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index 1e8c30b..a011ae2 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -147,6 +147,14 @@ sp<ICamera> CameraService::connect( return NULL; } + char value[PROPERTY_VALUE_MAX]; + property_get("sys.secpolicy.camera.disabled", value, "0"); + if (strcmp(value, "1") == 0) { + // Camera is disabled by DevicePolicyManager. + LOGI("Camera is disabled. connect X (pid %d) rejected", callingPid); + return NULL; + } + Mutex::Autolock lock(mServiceLock); if (mClient[cameraId] != 0) { client = mClient[cameraId].promote(); diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java index fd502d8..158c778 100644 --- a/services/java/com/android/server/AppWidgetService.java +++ b/services/java/com/android/server/AppWidgetService.java @@ -395,41 +395,47 @@ class AppWidgetService extends IAppWidgetService.Stub public void bindAppWidgetId(int appWidgetId, ComponentName provider) { mContext.enforceCallingPermission(android.Manifest.permission.BIND_APPWIDGET, "bindGagetId appWidgetId=" + appWidgetId + " provider=" + provider); - synchronized (mAppWidgetIds) { - AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId); - if (id == null) { - throw new IllegalArgumentException("bad appWidgetId"); - } - if (id.provider != null) { - throw new IllegalArgumentException("appWidgetId " + appWidgetId + " already bound to " - + id.provider.info.provider); - } - Provider p = lookupProviderLocked(provider); - if (p == null) { - throw new IllegalArgumentException("not a appwidget provider: " + provider); - } - if (p.zombie) { - throw new IllegalArgumentException("can't bind to a 3rd party provider in" - + " safe mode: " + provider); - } - - id.provider = p; - p.instances.add(id); - int instancesSize = p.instances.size(); - if (instancesSize == 1) { - // tell the provider that it's ready - sendEnableIntentLocked(p); + + final long ident = Binder.clearCallingIdentity(); + try { + synchronized (mAppWidgetIds) { + AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId); + if (id == null) { + throw new IllegalArgumentException("bad appWidgetId"); + } + if (id.provider != null) { + throw new IllegalArgumentException("appWidgetId " + appWidgetId + " already bound to " + + id.provider.info.provider); + } + Provider p = lookupProviderLocked(provider); + if (p == null) { + throw new IllegalArgumentException("not a appwidget provider: " + provider); + } + if (p.zombie) { + throw new IllegalArgumentException("can't bind to a 3rd party provider in" + + " safe mode: " + provider); + } + + id.provider = p; + p.instances.add(id); + int instancesSize = p.instances.size(); + if (instancesSize == 1) { + // tell the provider that it's ready + sendEnableIntentLocked(p); + } + + // send an update now -- We need this update now, and just for this appWidgetId. + // It's less critical when the next one happens, so when we schdule the next one, + // we add updatePeriodMillis to its start time. That time will have some slop, + // but that's okay. + sendUpdateIntentLocked(p, new int[] { appWidgetId }); + + // schedule the future updates + registerForBroadcastsLocked(p, getAppWidgetIds(p)); + saveStateLocked(); } - - // send an update now -- We need this update now, and just for this appWidgetId. - // It's less critical when the next one happens, so when we schdule the next one, - // we add updatePeriodMillis to its start time. That time will have some slop, - // but that's okay. - sendUpdateIntentLocked(p, new int[] { appWidgetId }); - - // schedule the future updates - registerForBroadcastsLocked(p, getAppWidgetIds(p)); - saveStateLocked(); + } finally { + Binder.restoreCallingIdentity(ident); } } diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index c6f4c20..07855d9 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -16,8 +16,7 @@ package com.android.server; -import static android.Manifest.permission.READ_PHONE_STATE; -import static android.Manifest.permission.UPDATE_DEVICE_STATS; +import static android.Manifest.permission.MANAGE_NETWORK_POLICY; import static android.net.ConnectivityManager.isNetworkTypeValid; import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; import static android.net.NetworkPolicyManager.RULE_REJECT_PAID; @@ -48,7 +47,6 @@ import android.net.RouteInfo; import android.net.vpn.VpnManager; import android.net.wifi.WifiStateTracker; import android.os.Binder; -import android.os.Bundle; import android.os.FileUtils; import android.os.Handler; import android.os.HandlerThread; @@ -67,6 +65,7 @@ import android.util.EventLog; import android.util.Slog; import android.util.SparseIntArray; +import com.android.internal.net.VpnConfig; import com.android.internal.telephony.Phone; import com.android.server.connectivity.Tethering; import com.android.server.connectivity.Vpn; @@ -1142,8 +1141,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { @Override public void onRulesChanged(int uid, int uidRules) { // only someone like NPMS should only be calling us - // TODO: create permission for modifying data policy - mContext.enforceCallingOrSelfPermission(UPDATE_DEVICE_STATS, TAG); + mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); if (LOGD_RULES) { Slog.d(TAG, "onRulesChanged(uid=" + uid + ", uidRules=" + uidRules + ")"); @@ -1267,8 +1265,30 @@ public class ConnectivityService extends IConnectivityManager.Stub { } } intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished); + + // Reset interface if no other connections are using the same interface + boolean doReset = true; + LinkProperties linkProperties = mNetTrackers[prevNetType].getLinkProperties(); + if (linkProperties != null) { + String oldIface = linkProperties.getInterfaceName(); + if (TextUtils.isEmpty(oldIface) == false) { + for (NetworkStateTracker networkStateTracker : mNetTrackers) { + if (networkStateTracker == null) continue; + NetworkInfo networkInfo = networkStateTracker.getNetworkInfo(); + if (networkInfo.isConnected() && networkInfo.getType() != prevNetType) { + LinkProperties l = networkStateTracker.getLinkProperties(); + if (l == null) continue; + if (oldIface.equals(l.getInterfaceName())) { + doReset = false; + break; + } + } + } + } + } + // do this before we broadcast the change - handleConnectivityChange(prevNetType); + handleConnectivityChange(prevNetType, doReset); sendStickyBroadcast(intent); /* @@ -1490,7 +1510,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { } thisNet.setTeardownRequested(false); updateNetworkSettings(thisNet); - handleConnectivityChange(type); + handleConnectivityChange(type, false); sendConnectedBroadcast(info); } @@ -1500,7 +1520,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { * according to which networks are connected, and ensuring that the * right routing table entries exist. */ - private void handleConnectivityChange(int netType) { + private void handleConnectivityChange(int netType, boolean doReset) { /* * If a non-default network is enabled, add the host routes that * will allow it's DNS servers to be accessed. @@ -1540,6 +1560,17 @@ public class ConnectivityService extends IConnectivityManager.Stub { removePrivateDnsRoutes(mNetTrackers[netType]); } } + + if (doReset) { + LinkProperties linkProperties = mNetTrackers[netType].getLinkProperties(); + if (linkProperties != null) { + String iface = linkProperties.getInterfaceName(); + if (TextUtils.isEmpty(iface) == false) { + if (DBG) log("resetConnections(" + iface + ")"); + NetworkUtils.resetConnections(iface); + } + } + } } private void addPrivateDnsRoutes(NetworkStateTracker nt) { @@ -1965,7 +1996,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { break; case NetworkStateTracker.EVENT_CONFIGURATION_CHANGED: info = (NetworkInfo) msg.obj; - handleConnectivityChange(info.getType()); + handleConnectivityChange(info.getType(), true); break; case EVENT_CLEAR_NET_TRANSITION_WAKELOCK: String causedBy = null; @@ -2396,24 +2427,37 @@ public class ConnectivityService extends IConnectivityManager.Stub { return value; } - // @see ConnectivityManager#protectVpn(ParcelFileDescriptor) - // Permission checks are done in Vpn class. + /** + * Protect a socket from VPN routing rules. This method is used by + * VpnBuilder and not available in ConnectivityManager. Permission + * checks are done in Vpn class. + * @hide + */ @Override public void protectVpn(ParcelFileDescriptor socket) { mVpn.protect(socket, getDefaultInterface()); } - // @see ConnectivityManager#prepareVpn(String) - // Permission checks are done in Vpn class. + /** + * Prepare for a VPN application. This method is used by VpnDialogs + * and not available in ConnectivityManager. Permission checks are + * done in Vpn class. + * @hide + */ @Override public String prepareVpn(String packageName) { return mVpn.prepare(packageName); } - // @see ConnectivityManager#establishVpn(Bundle) - // Permission checks are done in Vpn class. + /** + * Configure a TUN interface and return its file descriptor. Parameters + * are encoded and opaque to this class. This method is used by VpnBuilder + * and not available in ConnectivityManager. Permission checks are done + * in Vpn class. + * @hide + */ @Override - public ParcelFileDescriptor establishVpn(Bundle config) { + public ParcelFileDescriptor establishVpn(VpnConfig config) { return mVpn.establish(config); } diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java index 2190b30..bb0c671 100644 --- a/services/java/com/android/server/NetworkManagementService.java +++ b/services/java/com/android/server/NetworkManagementService.java @@ -311,6 +311,18 @@ class NetworkManagementService extends INetworkManagementService.Stub { } } + /* TODO: This is right now a IPv4 only function. Works for wifi which loses its + IPv6 addresses on interface down, but we need to do full clean up here */ + public void clearInterfaceAddresses(String iface) throws IllegalStateException { + String cmd = String.format("interface clearaddrs %s", iface); + try { + mConnector.doCommand(cmd); + } catch (NativeDaemonConnectorException e) { + throw new IllegalStateException( + "Unable to communicate with native daemon to interface clearallips - " + e); + } + } + public void addRoute(String interfaceName, RouteInfo route) { modifyRoute(interfaceName, ADD, route); } diff --git a/services/java/com/android/server/StatusBarManagerService.java b/services/java/com/android/server/StatusBarManagerService.java index b1bce50..286a937 100644 --- a/services/java/com/android/server/StatusBarManagerService.java +++ b/services/java/com/android/server/StatusBarManagerService.java @@ -345,6 +345,15 @@ public class StatusBarManagerService extends IStatusBarService.Stub }); } + @Override + public void toggleRecentApps() { + if (mBar != null) { + try { + mBar.toggleRecentApps(); + } catch (RemoteException ex) {} + } + } + private void enforceStatusBar() { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR, "StatusBarManagerService"); diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java index ec59da6..a9dfb22 100644 --- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -441,6 +441,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub if (oldService != null) { tryRemoveServiceLocked(oldService); } + // This API is intended for testing so enable accessibility to make + // sure clients can start poking with the window content. + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_ENABLED, 1); + // Also disable all accessibility services to avoid interference + // with the tests. + Settings.Secure.putString(mContext.getContentResolver(), + Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, ""); } AccessibilityServiceInfo accessibilityServiceInfo = new AccessibilityServiceInfo(); accessibilityServiceInfo.eventTypes = AccessibilityEvent.TYPES_ALL_MASK; 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 941ab80..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; @@ -29,12 +28,12 @@ import android.graphics.Canvas; import android.graphics.drawable.Drawable; import android.net.INetworkManagementEventObserver; import android.os.Binder; -import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.util.Log; import com.android.internal.R; +import com.android.internal.net.VpnConfig; import com.android.server.ConnectivityService.VpnCallback; /** @@ -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 + } + } } /** @@ -108,7 +126,7 @@ public class Vpn extends INetworkManagementEventObserver.Stub { * @param configuration The parameters to configure the interface. * @return The file descriptor of the interface. */ - public synchronized ParcelFileDescriptor establish(Bundle config) { + public synchronized ParcelFileDescriptor establish(VpnConfig config) { // Check the permission of the caller. mContext.enforceCallingPermission(VPN, "establish"); @@ -118,23 +136,15 @@ 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; } - // Unpack the config. - // TODO: move constants into VpnBuilder. - int mtu = config.getInt("mtu", -1); - String session = config.getString("session"); - String addresses = config.getString("addresses"); - String routes = config.getString("routes"); - String dnsServers = config.getString("dnsServers"); - // Create and configure the interface. - ParcelFileDescriptor descriptor = - ParcelFileDescriptor.adoptFd(nativeEstablish(mtu, addresses, routes)); + ParcelFileDescriptor descriptor = ParcelFileDescriptor.adoptFd( + nativeEstablish(config.mtu, config.addresses, config.routes)); // Replace the interface and abort if it fails. try { @@ -153,10 +163,12 @@ public class Vpn extends INetworkManagementEventObserver.Stub { throw e; } - dnsServers = (dnsServers == null) ? "" : dnsServers.trim(); + String dnsServers = (config.dnsServers == null) ? "" : config.dnsServers.trim(); mCallback.override(dnsServers.isEmpty() ? null : dnsServers.split(" ")); - showNotification(pm, app, session); + config.packageName = mPackageName; + config.interfaceName = mInterfaceName; + showNotification(pm, app, config); return descriptor; } @@ -177,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); @@ -198,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) @@ -219,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/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java index dac0044..9cbe82d 100644 --- a/services/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java @@ -747,6 +747,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { @Override public void registerListener(INetworkPolicyListener listener) { + // TODO: create permission for observing network policy + mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); + mListeners.register(listener); synchronized (mRulesLock) { @@ -767,6 +770,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { @Override public void unregisterListener(INetworkPolicyListener listener) { + // TODO: create permission for observing network policy + mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); + mListeners.unregister(listener); } diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java index f762123..0a84bc7 100644 --- a/services/java/com/android/server/net/NetworkStatsService.java +++ b/services/java/com/android/server/net/NetworkStatsService.java @@ -225,7 +225,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mContext.unregisterReceiver(mShutdownReceiver); writeNetworkStatsLocked(); - writeUidStatsLocked(); + if (mUidStatsLoaded) { + writeUidStatsLocked(); + } mNetworkStats.clear(); mUidStats.clear(); mUidStatsLoaded = false; @@ -442,7 +444,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub { if (persistDelta.rx[index] > persistThreshold || persistDelta.tx[index] > persistThreshold) { writeNetworkStatsLocked(); - writeUidStatsLocked(); + if (mUidStatsLoaded) { + writeUidStatsLocked(); + } mLastNetworkPersist = networkStats; break; } 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/services/jni/com_android_server_connectivity_Vpn.cpp b/services/jni/com_android_server_connectivity_Vpn.cpp index 206df25..ae7fbfe 100644 --- a/services/jni/com_android_server_connectivity_Vpn.cpp +++ b/services/jni/com_android_server_connectivity_Vpn.cpp @@ -55,6 +55,7 @@ static int create_interface(int mtu, char *name, int *index) { int tun = open("/dev/tun", O_RDWR); int inet4 = socket(AF_INET, SOCK_DGRAM, 0); + int flags; ifreq ifr4; memset(&ifr4, 0, sizeof(ifr4)); @@ -86,6 +87,13 @@ static int create_interface(int mtu, char *name, int *index) goto error; } + // Make it non-blocking. + flags = fcntl(tun, F_GETFL, 0); + if (flags == -1 || fcntl(tun, F_SETFL, flags | O_NONBLOCK)) { + LOGE("Cannot set non-blocking on %s: %s", ifr4.ifr_name, strerror(errno)); + goto error; + } + strcpy(name, ifr4.ifr_name); *index = ifr4.ifr_ifindex; close(inet4); diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml index 151fde7..ee5f3f5 100644 --- a/services/tests/servicestests/AndroidManifest.xml +++ b/services/tests/servicestests/AndroidManifest.xml @@ -28,6 +28,7 @@ <uses-permission android:name="android.permission.MANAGE_APP_TOKENS" /> <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" /> <uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" /> + <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" /> <application> <uses-library android:name="android.test.runner" /> diff --git a/telephony/java/com/android/internal/telephony/IccCard.java b/telephony/java/com/android/internal/telephony/IccCard.java index 5d8fc78..02617c8 100644 --- a/telephony/java/com/android/internal/telephony/IccCard.java +++ b/telephony/java/com/android/internal/telephony/IccCard.java @@ -84,6 +84,9 @@ public abstract class IccCard { static public final String INTENT_VALUE_LOCKED_ON_PUK = "PUK"; /* NETWORK means ICC is locked on NETWORK PERSONALIZATION */ static public final String INTENT_VALUE_LOCKED_NETWORK = "NETWORK"; + /* PERM_DISABLED means ICC is permanently disabled due to puk fails */ + static public final String INTENT_VALUE_ABSENT_ON_PERM_DISABLED = "PERM_DISABLED"; + protected static final int EVENT_ICC_LOCKED_OR_ABSENT = 1; private static final int EVENT_GET_ICC_STATUS_DONE = 2; @@ -112,7 +115,8 @@ public abstract class IccCard { PUK_REQUIRED, NETWORK_LOCKED, READY, - NOT_READY; + NOT_READY, + PERM_DISABLED; public boolean isPinLocked() { return ((this == PIN_REQUIRED) || (this == PUK_REQUIRED)); @@ -120,7 +124,8 @@ public abstract class IccCard { public boolean iccCardExist() { return ((this == PIN_REQUIRED) || (this == PUK_REQUIRED) - || (this == NETWORK_LOCKED) || (this == READY)); + || (this == NETWORK_LOCKED) || (this == READY) + || (this == PERM_DISABLED)); } } @@ -416,6 +421,7 @@ public abstract class IccCard { boolean transitionedIntoPinLocked; boolean transitionedIntoAbsent; boolean transitionedIntoNetworkLocked; + boolean transitionedIntoPermBlocked; boolean isIccCardRemoved; boolean isIccCardAdded; @@ -434,6 +440,8 @@ public abstract class IccCard { transitionedIntoAbsent = (oldState != State.ABSENT && newState == State.ABSENT); transitionedIntoNetworkLocked = (oldState != State.NETWORK_LOCKED && newState == State.NETWORK_LOCKED); + transitionedIntoPermBlocked = (oldState != State.PERM_DISABLED + && newState == State.PERM_DISABLED); isIccCardRemoved = (oldState != null && oldState.iccCardExist() && newState == State.ABSENT); isIccCardAdded = (oldState == State.ABSENT && @@ -454,6 +462,10 @@ public abstract class IccCard { mNetworkLockedRegistrants.notifyRegistrants(); broadcastIccStateChangedIntent(INTENT_VALUE_ICC_LOCKED, INTENT_VALUE_LOCKED_NETWORK); + } else if (transitionedIntoPermBlocked) { + if (mDbg) log("Notify SIM permanently disabled."); + broadcastIccStateChangedIntent(INTENT_VALUE_ICC_ABSENT, + INTENT_VALUE_ABSENT_ON_PERM_DISABLED); } if (isIccCardRemoved) { @@ -762,6 +774,9 @@ public abstract class IccCard { } // check if PIN required + if (app.pin1.isPermBlocked()) { + return IccCard.State.PERM_DISABLED; + } if (app.app_state.isPinRequired()) { return IccCard.State.PIN_REQUIRED; } diff --git a/telephony/java/com/android/internal/telephony/IccCardApplication.java b/telephony/java/com/android/internal/telephony/IccCardApplication.java index 434c484..abb740e 100644 --- a/telephony/java/com/android/internal/telephony/IccCardApplication.java +++ b/telephony/java/com/android/internal/telephony/IccCardApplication.java @@ -16,6 +16,8 @@ package com.android.internal.telephony; +import com.android.internal.telephony.IccCardStatus.PinState; + /** * See also RIL_AppStatus in include/telephony/ril.h @@ -104,8 +106,8 @@ public class IccCardApplication { public String app_label; // applicable to USIM and CSIM public int pin1_replaced; - public int pin1; - public int pin2; + public PinState pin1; + public PinState pin2; AppType AppTypeFromRILInt(int type) { AppType newType; @@ -177,6 +179,33 @@ public class IccCardApplication { return newSubState; } + PinState PinStateFromRILInt(int state) { + PinState newPinState; + switch(state) { + case 0: + newPinState = PinState.PINSTATE_UNKNOWN; + break; + case 1: + newPinState = PinState.PINSTATE_ENABLED_NOT_VERIFIED; + break; + case 2: + newPinState = PinState.PINSTATE_ENABLED_VERIFIED; + break; + case 3: + newPinState = PinState.PINSTATE_DISABLED; + break; + case 4: + newPinState = PinState.PINSTATE_ENABLED_BLOCKED; + break; + case 5: + newPinState = PinState.PINSTATE_ENABLED_PERM_BLOCKED; + break; + default: + throw new RuntimeException("Unrecognized RIL_PinState: " + state); + } + return newPinState; + } + @Override public String toString() { StringBuilder sb = new StringBuilder(); @@ -185,6 +214,12 @@ public class IccCardApplication { if (app_state == AppState.APPSTATE_SUBSCRIPTION_PERSO) { sb.append(",").append(perso_substate); } + if (app_type == AppType.APPTYPE_CSIM || + app_type == AppType.APPTYPE_USIM || + app_type == AppType.APPTYPE_ISIM) { + sb.append(",pin1=").append(pin1); + sb.append(",pin2=").append(pin2); + } sb.append("}"); return sb.toString(); } diff --git a/telephony/java/com/android/internal/telephony/IccCardStatus.java b/telephony/java/com/android/internal/telephony/IccCardStatus.java index e9de922..c751a21 100644 --- a/telephony/java/com/android/internal/telephony/IccCardStatus.java +++ b/telephony/java/com/android/internal/telephony/IccCardStatus.java @@ -42,7 +42,19 @@ public class IccCardStatus { PINSTATE_ENABLED_VERIFIED, PINSTATE_DISABLED, PINSTATE_ENABLED_BLOCKED, - PINSTATE_ENABLED_PERM_BLOCKED + PINSTATE_ENABLED_PERM_BLOCKED; + + boolean isPermBlocked() { + return this == PINSTATE_ENABLED_PERM_BLOCKED; + } + + boolean isPinRequired() { + return this == PINSTATE_ENABLED_NOT_VERIFIED; + } + + boolean isPukRequired() { + return this == PINSTATE_ENABLED_BLOCKED; + } } private CardState mCardState; diff --git a/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java b/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java index 5fef6de..9763265 100644 --- a/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java +++ b/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java @@ -112,7 +112,7 @@ public abstract class IccSmsInterfaceManager extends ISms.Stub { */ public void sendText(String destAddr, String scAddr, String text, PendingIntent sentIntent, PendingIntent deliveryIntent) { - mPhone.getContext().enforceCallingPermission( + mPhone.getContext().enforceCallingOrSelfPermission( "android.permission.SEND_SMS", "Sending SMS message"); if (Log.isLoggable("SMS", Log.VERBOSE)) { diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java index 572bbaa..76f1ab7 100644 --- a/telephony/java/com/android/internal/telephony/RIL.java +++ b/telephony/java/com/android/internal/telephony/RIL.java @@ -2924,8 +2924,8 @@ public final class RIL extends BaseCommands implements CommandsInterface { ca.aid = p.readString(); ca.app_label = p.readString(); ca.pin1_replaced = p.readInt(); - ca.pin1 = p.readInt(); - ca.pin2 = p.readInt(); + ca.pin1 = ca.PinStateFromRILInt(p.readInt()); + ca.pin2 = ca.PinStateFromRILInt(p.readInt()); status.addApplication(ca); } return status; diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java index ee63ede..9af2d26 100755 --- a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java +++ b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java @@ -119,8 +119,11 @@ public final class RuimRecords extends IccRecords { adnCache.reset(); - phone.setSystemProperty(PROPERTY_ICC_OPERATOR_NUMERIC, null); - phone.setSystemProperty(PROPERTY_ICC_OPERATOR_ISO_COUNTRY, null); + // Don't clean up PROPERTY_ICC_OPERATOR_ISO_COUNTRY and + // PROPERTY_ICC_OPERATOR_NUMERIC here. Since not all CDMA + // devices have RUIM, these properties should keep the original + // values, e.g. build time settings, when there is no RUIM but + // set new values when RUIM is available and loaded. // recordsRequested is set to false indicating that the SIM // read requests made so far are not valid. This is set to diff --git a/tests/BiDiTests/res/layout/view_padding.xml b/tests/BiDiTests/res/layout/view_padding.xml new file mode 100644 index 0000000..1652d04 --- /dev/null +++ b/tests/BiDiTests/res/layout/view_padding.xml @@ -0,0 +1,156 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2011 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. +--> + +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/view_padding" + android:layout_width="fill_parent" + android:layout_height="fill_parent"> + + <FrameLayout android:layout_width="match_parent" + android:layout_height="match_parent"> + + <FrameLayout + android:layout_width="300dp" + android:layout_height="300dp" + android:layout_gravity="top|left" + android:background="#FF888888" + android:paddingTop="20dip" + android:paddingLeft="40dip" + android:paddingBottom="30dip" + android:paddingRight="50dip"> + + <FrameLayout + android:layout_width="100dp" + android:layout_height="100dp" + android:layout_gravity="top|left" + android:background="#FF0000FF"> + </FrameLayout> + + <FrameLayout + android:layout_width="100dp" + android:layout_height="100dp" + android:layout_gravity="bottom|right" + android:background="#FF00FF00"> + </FrameLayout> + </FrameLayout> + + <FrameLayout + android:layout_width="300dp" + android:layout_height="300dp" + android:layout_gravity="top|center_horizontal" + android:background="#FF888888" + android:paddingTop="20dip" + android:paddingLeft="40dip" + android:paddingBottom="30dip" + android:paddingRight="50dip" + android:layoutDirection="inherit"> + + <FrameLayout + android:layout_width="100dp" + android:layout_height="100dp" + android:layout_gravity="top|left" + android:background="#FF0000FF"> + </FrameLayout> + + <FrameLayout + android:layout_width="100dp" + android:layout_height="100dp" + android:layout_gravity="bottom|right" + android:background="#FF00FF00"> + </FrameLayout> + </FrameLayout> + + <FrameLayout + android:layout_width="300dp" + android:layout_height="300dp" + android:layout_gravity="top|right" + android:background="#FF888888" + android:paddingTop="20dip" + android:paddingLeft="40dip" + android:paddingBottom="30dip" + android:paddingRight="50dip" + android:layoutDirection="ltr"> + + <FrameLayout + android:layout_width="100dp" + android:layout_height="100dp" + android:layout_gravity="top|left" + android:background="#FF0000FF"> + </FrameLayout> + + <FrameLayout + android:layout_width="100dp" + android:layout_height="100dp" + android:layout_gravity="bottom|right" + android:background="#FF00FF00"> + </FrameLayout> + </FrameLayout> + + <FrameLayout + android:layout_width="300dp" + android:layout_height="300dp" + android:layout_gravity="bottom|left" + android:background="#FF888888" + android:paddingTop="20dip" + android:paddingLeft="40dip" + android:paddingBottom="30dip" + android:paddingRight="50dip" + android:layoutDirection="rtl"> + + <FrameLayout + android:layout_width="100dp" + android:layout_height="100dp" + android:layout_gravity="top|left" + android:background="#FF0000FF"> + </FrameLayout> + + <FrameLayout + android:layout_width="100dp" + android:layout_height="100dp" + android:layout_gravity="bottom|right" + android:background="#FF00FF00"> + </FrameLayout> + </FrameLayout> + + <FrameLayout + android:layout_width="300dp" + android:layout_height="300dp" + android:layout_gravity="bottom|center_horizontal" + android:background="#FF888888" + android:paddingTop="20dip" + android:paddingLeft="40dip" + android:paddingBottom="30dip" + android:paddingRight="50dip" + android:layoutDirection="locale"> + + <FrameLayout + android:layout_width="100dp" + android:layout_height="100dp" + android:layout_gravity="top|left" + android:background="#FF0000FF"> + </FrameLayout> + + <FrameLayout + android:layout_width="100dp" + android:layout_height="100dp" + android:layout_gravity="bottom|right" + android:background="#FF00FF00"> + </FrameLayout> + </FrameLayout> + + </FrameLayout> + +</FrameLayout> diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java index a3a0041..0bed7ce 100644 --- a/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java @@ -119,6 +119,8 @@ public class BiDiTestActivity extends Activity { addItem(result, "Table RTL", BiDiTestTableLayoutRtl.class, R.id.table_layout_rtl); addItem(result, "Table LOC", BiDiTestTableLayoutLocale.class, R.id.table_layout_locale); + addItem(result, "ViewPadding", BiDiTestViewPadding.class, R.id.view_padding); + return result; } }
\ No newline at end of file diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestViewPadding.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestViewPadding.java new file mode 100644 index 0000000..6bb410a --- /dev/null +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestViewPadding.java @@ -0,0 +1,17 @@ +// Copyright 2011 Google Inc. All Rights Reserved. +package com.android.bidi; + +import android.app.Fragment; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +public class BiDiTestViewPadding extends Fragment { + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + return inflater.inflate(R.layout.view_padding, container, false); + } +} diff --git a/tests/GridLayoutTest/res/layout/grid3.xml b/tests/GridLayoutTest/res/layout/grid3.xml index 5cdacf7..ba911c2 100644 --- a/tests/GridLayoutTest/res/layout/grid3.xml +++ b/tests/GridLayoutTest/res/layout/grid3.xml @@ -21,7 +21,7 @@ android:layout_height="match_parent" android:useDefaultMargins="true" - android:marginsIncludedInAlignment="false" + android:alignmentMode="alignBounds" android:columnCount="4" > diff --git a/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java b/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java index 32365d7..e010a00 100644 --- a/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java +++ b/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java @@ -36,7 +36,7 @@ public class Activity2 extends Activity { public static View create(Context context) { GridLayout vg = new GridLayout(context); vg.setUseDefaultMargins(true); - vg.setMarginsIncludedInAlignment(false); + vg.setAlignmentMode(ALIGN_BOUNDS); Group row1 = new Group(1, CENTER); Group row2 = new Group(2, CENTER); 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); + } + } +} diff --git a/tests/RenderScriptTests/FBOTest/AndroidManifest.xml b/tests/RenderScriptTests/FBOTest/AndroidManifest.xml index c2e0cc6..788e856 100644 --- a/tests/RenderScriptTests/FBOTest/AndroidManifest.xml +++ b/tests/RenderScriptTests/FBOTest/AndroidManifest.xml @@ -3,11 +3,20 @@ package="com.android.fbotest"> <application android:label="_FBOTest"> <activity android:name="FBOTest" + android:label="FBO Base Test" android:theme="@android:style/Theme.Black.NoTitleBar"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> - </activity> + </activity> + <activity android:name="FBOSync" + android:label="FBO Sync Test" + android:theme="@android:style/Theme.Black.NoTitleBar"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> </application> </manifest> diff --git a/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/FBOSync.java b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/FBOSync.java new file mode 100644 index 0000000..d30ad7e --- /dev/null +++ b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/FBOSync.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2011 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.fbotest; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; + +import android.app.Activity; +import android.content.res.Configuration; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.provider.Settings.System; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.MenuInflater; +import android.view.Window; +import android.widget.Button; +import android.widget.ListView; +import android.net.Uri; + +import java.lang.Runtime; + +public class FBOSync extends Activity { + + private FBOSyncView mView; + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + // Create our Preview view and set it as the content of our + // Activity + mView = new FBOSyncView(this); + setContentView(mView); + } + + @Override + protected void onResume() { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onResume(); + mView.resume(); + } + + @Override + protected void onPause() { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onPause(); + mView.pause(); + } +} + diff --git a/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/FBOSyncRS.java b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/FBOSyncRS.java new file mode 100644 index 0000000..57a117c --- /dev/null +++ b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/FBOSyncRS.java @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2011 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.fbotest; + +import java.io.Writer; + +import android.content.res.Resources; +import android.renderscript.*; +import android.renderscript.Element.DataType; +import android.renderscript.Element.DataKind; +import android.renderscript.ProgramStore.DepthFunc; +import android.renderscript.Type.Builder; +import android.util.Log; + + +public class FBOSyncRS { + + public FBOSyncRS() { + } + + public void init(RenderScriptGL rs, Resources res) { + mRS = rs; + mRes = res; + initRS(); + } + + public void surfaceChanged() { + mRS.getWidth(); + mRS.getHeight(); + } + + private Resources mRes; + private RenderScriptGL mRS; + private Sampler mSampler; + private ProgramStore mPSBackground; + private ProgramFragment mPFBackground; + private ProgramVertex mPVBackground; + private ProgramVertexFixedFunction.Constants mPVA; + + private Allocation mGridImage; + private Allocation mOffscreen; + private Allocation mOffscreenDepth; + private Allocation mAllocPV; + private Allocation mReadBackTest; + + private Font mItalic; + private Allocation mTextAlloc; + + private ScriptField_MeshInfo mMeshes; + private ScriptC_fbosync mScript; + + + public void onActionDown(float x, float y) { + mScript.invoke_onActionDown(x, y); + } + + public void onActionScale(float scale) { + mScript.invoke_onActionScale(scale); + } + + public void onActionMove(float x, float y) { + mScript.invoke_onActionMove(x, y); + } + + private void initPFS() { + ProgramStore.Builder b = new ProgramStore.Builder(mRS); + + b.setDepthFunc(ProgramStore.DepthFunc.LESS); + b.setDitherEnabled(false); + b.setDepthMaskEnabled(true); + mPSBackground = b.create(); + + mScript.set_gPFSBackground(mPSBackground); + } + + private void initPF() { + Sampler.Builder bs = new Sampler.Builder(mRS); + bs.setMinification(Sampler.Value.LINEAR); + bs.setMagnification(Sampler.Value.LINEAR); + bs.setWrapS(Sampler.Value.CLAMP); + bs.setWrapT(Sampler.Value.CLAMP); + mSampler = bs.create(); + + ProgramFragmentFixedFunction.Builder b = new ProgramFragmentFixedFunction.Builder(mRS); + b.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE, + ProgramFragmentFixedFunction.Builder.Format.RGBA, 0); + mPFBackground = b.create(); + mPFBackground.bindSampler(mSampler, 0); + + mScript.set_gPFBackground(mPFBackground); + } + + private void initPV() { + ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS); + mPVBackground = pvb.create(); + + mPVA = new ProgramVertexFixedFunction.Constants(mRS); + ((ProgramVertexFixedFunction)mPVBackground).bindConstants(mPVA); + + mScript.set_gPVBackground(mPVBackground); + } + + private void loadImage() { + mGridImage = Allocation.createFromBitmapResource(mRS, mRes, R.drawable.robot, + Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE, + Allocation.USAGE_GRAPHICS_TEXTURE); + mScript.set_gTGrid(mGridImage); + } + + private void initTextAllocation(String fileName) { + String allocString = "Displaying file: " + fileName; + mTextAlloc = Allocation.createFromString(mRS, allocString, Allocation.USAGE_SCRIPT); + mScript.set_gTextAlloc(mTextAlloc); + } + + private void initMeshes(FileA3D model) { + int numEntries = model.getIndexEntryCount(); + int numMeshes = 0; + for (int i = 0; i < numEntries; i ++) { + FileA3D.IndexEntry entry = model.getIndexEntry(i); + if (entry != null && entry.getEntryType() == FileA3D.EntryType.MESH) { + numMeshes ++; + } + } + + if (numMeshes > 0) { + mMeshes = new ScriptField_MeshInfo(mRS, numMeshes); + + for (int i = 0; i < numEntries; i ++) { + FileA3D.IndexEntry entry = model.getIndexEntry(i); + if (entry != null && entry.getEntryType() == FileA3D.EntryType.MESH) { + Mesh mesh = entry.getMesh(); + mMeshes.set_mMesh(i, mesh, false); + mMeshes.set_mNumIndexSets(i, mesh.getPrimitiveCount(), false); + } + } + mMeshes.copyAll(); + } else { + throw new RSRuntimeException("No valid meshes in file"); + } + + mScript.bind_gMeshes(mMeshes); + mScript.invoke_updateMeshInfo(); + } + + public void loadA3DFile(String path) { + FileA3D model = FileA3D.createFromFile(mRS, path); + initMeshes(model); + initTextAllocation(path); + } + + private void initRS() { + + mScript = new ScriptC_fbosync(mRS, mRes, R.raw.fbosync); + + initPFS(); + initPF(); + initPV(); + + loadImage(); + + Type.Builder b = new Type.Builder(mRS, Element.RGBA_8888(mRS)); + b.setX(512).setY(512); + mOffscreen = Allocation.createTyped(mRS, + b.create(), + Allocation.USAGE_SCRIPT | + Allocation.USAGE_GRAPHICS_TEXTURE | + Allocation.USAGE_GRAPHICS_RENDER_TARGET); + mScript.set_gOffscreen(mOffscreen); + + mReadBackTest = Allocation.createTyped(mRS, + b.create(), + Allocation.USAGE_SCRIPT | + Allocation.USAGE_GRAPHICS_TEXTURE); + mScript.set_gReadBackTest(mReadBackTest); + + b = new Type.Builder(mRS, + Element.createPixel(mRS, DataType.UNSIGNED_16, + DataKind.PIXEL_DEPTH)); + b.setX(512).setY(512); + mOffscreenDepth = Allocation.createTyped(mRS, + b.create(), + Allocation.USAGE_GRAPHICS_RENDER_TARGET); + mScript.set_gOffscreenDepth(mOffscreenDepth); + + FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.robot); + initMeshes(model); + + mItalic = Font.create(mRS, mRes, "serif", Font.Style.ITALIC, 8); + mScript.set_gItalic(mItalic); + + initTextAllocation("R.raw.robot"); + + mRS.bindRootScript(mScript); + } +} + + + diff --git a/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/FBOSyncView.java b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/FBOSyncView.java new file mode 100644 index 0000000..6a85628 --- /dev/null +++ b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/FBOSyncView.java @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2011 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.fbotest; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScriptGL; + +import android.content.Context; +import android.view.MotionEvent; +import android.view.SurfaceHolder; +import android.view.ScaleGestureDetector; +import android.util.Log; + +public class FBOSyncView extends RSSurfaceView { + + private RenderScriptGL mRS; + private FBOSyncRS mRender; + + private ScaleGestureDetector mScaleDetector; + + private static final int INVALID_POINTER_ID = -1; + private int mActivePointerId = INVALID_POINTER_ID; + + public FBOSyncView(Context context) { + super(context); + ensureRenderScript(); + mScaleDetector = new ScaleGestureDetector(context, new ScaleListener()); + } + + private void ensureRenderScript() { + if (mRS == null) { + RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig(); + sc.setDepth(16, 24); + mRS = createRenderScriptGL(sc); + mRender = new FBOSyncRS(); + mRender.init(mRS, getResources()); + } + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + ensureRenderScript(); + } + + @Override + public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { + super.surfaceChanged(holder, format, w, h); + mRender.surfaceChanged(); + } + + @Override + protected void onDetachedFromWindow() { + mRender = null; + if (mRS != null) { + mRS = null; + destroyRenderScriptGL(); + } + } + + public void loadA3DFile(String path) { + mRender.loadA3DFile(path); + } + + @Override + public boolean onTouchEvent(MotionEvent ev) { + mScaleDetector.onTouchEvent(ev); + + boolean ret = false; + float x = ev.getX(); + float y = ev.getY(); + + final int action = ev.getAction(); + + switch (action & MotionEvent.ACTION_MASK) { + case MotionEvent.ACTION_DOWN: { + mRender.onActionDown(x, y); + mActivePointerId = ev.getPointerId(0); + ret = true; + break; + } + case MotionEvent.ACTION_MOVE: { + if (!mScaleDetector.isInProgress()) { + mRender.onActionMove(x, y); + } + mRender.onActionDown(x, y); + ret = true; + break; + } + + case MotionEvent.ACTION_UP: { + mActivePointerId = INVALID_POINTER_ID; + break; + } + + case MotionEvent.ACTION_CANCEL: { + mActivePointerId = INVALID_POINTER_ID; + break; + } + + case MotionEvent.ACTION_POINTER_UP: { + final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) + >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; + final int pointerId = ev.getPointerId(pointerIndex); + if (pointerId == mActivePointerId) { + // This was our active pointer going up. Choose a new + // active pointer and adjust accordingly. + final int newPointerIndex = pointerIndex == 0 ? 1 : 0; + x = ev.getX(newPointerIndex); + y = ev.getY(newPointerIndex); + mRender.onActionDown(x, y); + mActivePointerId = ev.getPointerId(newPointerIndex); + } + break; + } + } + + return ret; + } + + private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { + @Override + public boolean onScale(ScaleGestureDetector detector) { + mRender.onActionScale(detector.getScaleFactor()); + return true; + } + } +} + + diff --git a/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbosync.rs b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbosync.rs new file mode 100644 index 0000000..b77ccb4 --- /dev/null +++ b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbosync.rs @@ -0,0 +1,233 @@ +// Copyright (C) 2011 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. + +#pragma version(1) + +#pragma rs java_package_name(com.android.fbotest) + +#include "rs_graphics.rsh" + +rs_program_vertex gPVBackground; +rs_program_fragment gPFBackground; + +rs_allocation gTGrid; + +rs_program_store gPFSBackground; + +rs_font gItalic; +rs_allocation gTextAlloc; + +rs_allocation gOffscreen; +rs_allocation gOffscreenDepth; +rs_allocation gReadBackTest; + +typedef struct MeshInfo { + rs_mesh mMesh; + int mNumIndexSets; + float3 bBoxMin; + float3 bBoxMax; +} MeshInfo_t; + +MeshInfo_t *gMeshes; + +static float3 gLookAt; + +static float gRotateX; +static float gRotateY; +static float gZoom; + +static float gLastX; +static float gLastY; + +void onActionDown(float x, float y) { + gLastX = x; + gLastY = y; +} + +void onActionScale(float scale) { + + gZoom *= 1.0f / scale; + gZoom = max(0.1f, min(gZoom, 500.0f)); +} + +void onActionMove(float x, float y) { + float dx = gLastX - x; + float dy = gLastY - y; + + if (fabs(dy) <= 2.0f) { + dy = 0.0f; + } + if (fabs(dx) <= 2.0f) { + dx = 0.0f; + } + + gRotateY -= dx; + if (gRotateY > 360) { + gRotateY -= 360; + } + if (gRotateY < 0) { + gRotateY += 360; + } + + gRotateX -= dy; + gRotateX = min(gRotateX, 80.0f); + gRotateX = max(gRotateX, -80.0f); + + gLastX = x; + gLastY = y; +} + +void init() { + gRotateX = 0.0f; + gRotateY = 0.0f; + gZoom = 50.0f; + gLookAt = 0.0f; +} + +void updateMeshInfo() { + rs_allocation allMeshes = rsGetAllocation(gMeshes); + int size = rsAllocationGetDimX(allMeshes); + gLookAt = 0.0f; + float minX, minY, minZ, maxX, maxY, maxZ; + for (int i = 0; i < size; i++) { + MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i); + rsgMeshComputeBoundingBox(info->mMesh, + &minX, &minY, &minZ, + &maxX, &maxY, &maxZ); + info->bBoxMin = (minX, minY, minZ); + info->bBoxMax = (maxX, maxY, maxZ); + gLookAt += (info->bBoxMin + info->bBoxMax)*0.5f; + } + gLookAt = gLookAt / (float)size; +} + +static void renderAllMeshes() { + rs_allocation allMeshes = rsGetAllocation(gMeshes); + int size = rsAllocationGetDimX(allMeshes); + gLookAt = 0.0f; + float minX, minY, minZ, maxX, maxY, maxZ; + for (int i = 0; i < size; i++) { + MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i); + rsgDrawMesh(info->mMesh); + } +} + +static void drawDescription() { + uint width = rsgGetWidth(); + uint height = rsgGetHeight(); + int left = 0, right = 0, top = 0, bottom = 0; + + rsgBindFont(gItalic); + + rsgMeasureText(gTextAlloc, &left, &right, &top, &bottom); + rsgDrawText(gTextAlloc, 2 -left, height - 2 + bottom); +} + +static void renderOffscreen(bool useDepth) { + + rsgBindColorTarget(gOffscreen, 0); + if (useDepth) { + rsgBindDepthTarget(gOffscreenDepth); + rsgClearDepth(1.0f); + } else { + rsgClearDepthTarget(); + } + rsgClearColor(0.8f, 0.0f, 0.0f, 1.0f); + + rsgBindProgramVertex(gPVBackground); + rs_matrix4x4 proj; + float aspect = (float)rsAllocationGetDimX(gOffscreen) / (float)rsAllocationGetDimY(gOffscreen); + rsMatrixLoadPerspective(&proj, 30.0f, aspect, 1.0f, 100.0f); + rsgProgramVertexLoadProjectionMatrix(&proj); + + rsgBindProgramFragment(gPFBackground); + rsgBindProgramStore(gPFSBackground); + rsgBindTexture(gPFBackground, 0, gTGrid); + + rs_matrix4x4 matrix; + rsMatrixLoadIdentity(&matrix); + // Position our models on the screen + rsMatrixTranslate(&matrix, gLookAt.x, gLookAt.y, gLookAt.z - gZoom); + rsMatrixRotate(&matrix, gRotateX, 1.0f, 0.0f, 0.0f); + rsMatrixRotate(&matrix, gRotateY, 0.0f, 1.0f, 0.0f); + rsgProgramVertexLoadModelMatrix(&matrix); + + renderAllMeshes(); + + // Render into the frambuffer + rsgClearAllRenderTargets(); +} + +static void drawOffscreenResult(int posX, int posY, rs_allocation texture) { + // display the result + rs_matrix4x4 proj, matrix; + rsMatrixLoadOrtho(&proj, 0, rsgGetWidth(), rsgGetHeight(), 0, -500, 500); + rsgProgramVertexLoadProjectionMatrix(&proj); + rsMatrixLoadIdentity(&matrix); + rsgProgramVertexLoadModelMatrix(&matrix); + rsgBindTexture(gPFBackground, 0, texture); + float startX = posX, startY = posY; + float width = 256, height = 256; + rsgDrawQuadTexCoords(startX, startY, 0, 0, 1, + startX, startY + height, 0, 0, 0, + startX + width, startY + height, 0, 1, 0, + startX + width, startY, 0, 1, 1); +} + +int root(void) { + + rsgClearColor(1.0f, 1.0f, 1.0f, 1.0f); + rsgClearDepth(1.0f); + + renderOffscreen(true); + drawOffscreenResult(0, 0, gOffscreen); + + + uint32_t w = rsAllocationGetDimX(gOffscreen); + uint32_t h = rsAllocationGetDimY(gOffscreen); + uint32_t numElements = w*h; + + rsgAllocationSyncAll(gOffscreen, RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET); + + rsAllocationCopy2DRange(gReadBackTest, 0, 0, 0, + RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, w, h, + gOffscreen, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X); + + rsgAllocationSyncAll(gReadBackTest); + drawOffscreenResult(0, 300, gReadBackTest); + + rsgBindProgramVertex(gPVBackground); + rs_matrix4x4 proj; + float aspect = (float)rsgGetWidth() / (float)rsgGetHeight(); + rsMatrixLoadPerspective(&proj, 30.0f, aspect, 1.0f, 100.0f); + rsgProgramVertexLoadProjectionMatrix(&proj); + + rsgBindProgramFragment(gPFBackground); + rsgBindProgramStore(gPFSBackground); + rsgBindTexture(gPFBackground, 0, gTGrid); + + rs_matrix4x4 matrix; + rsMatrixLoadIdentity(&matrix); + // Position our models on the screen + rsMatrixTranslate(&matrix, gLookAt.x, gLookAt.y, gLookAt.z - gZoom); + rsMatrixRotate(&matrix, gRotateX, 1.0f, 0.0f, 0.0f); + rsMatrixRotate(&matrix, gRotateY, 0.0f, 1.0f, 0.0f); + rsgProgramVertexLoadModelMatrix(&matrix); + + renderAllMeshes(); + + drawDescription(); + + return 0; +} diff --git a/tests/RenderScriptTests/PerfTest/res/drawable/flares.png b/tests/RenderScriptTests/PerfTest/res/drawable/flares.png Binary files differnew file mode 100644 index 0000000..3a5c970 --- /dev/null +++ b/tests/RenderScriptTests/PerfTest/res/drawable/flares.png diff --git a/tests/RenderScriptTests/PerfTest/res/drawable/light1.jpg b/tests/RenderScriptTests/PerfTest/res/drawable/light1.jpg Binary files differnew file mode 100644 index 0000000..2f2f10e --- /dev/null +++ b/tests/RenderScriptTests/PerfTest/res/drawable/light1.jpg diff --git a/tests/RenderScriptTests/PerfTest/res/drawable/space.jpg b/tests/RenderScriptTests/PerfTest/res/drawable/space.jpg Binary files differnew file mode 100644 index 0000000..b61f6a3 --- /dev/null +++ b/tests/RenderScriptTests/PerfTest/res/drawable/space.jpg diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java index b568781..3f57799 100644 --- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java +++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java @@ -38,6 +38,10 @@ import android.renderscript.ProgramStore.BlendSrcFunc; import android.renderscript.ProgramStore.BlendDstFunc; import android.renderscript.RenderScript.RSMessageHandler; import android.renderscript.Sampler.Value; +import android.renderscript.Mesh.Primitive; +import android.renderscript.Matrix4f; +import android.renderscript.ProgramVertexFixedFunction; + import android.util.Log; @@ -45,7 +49,9 @@ public class RsBenchRS { private static final String TAG = "RsBenchRS"; private static final String SAMPLE_TEXT = "Bench Test"; - + private static final String LIST_TEXT = + "This is a sample list of text to show in the list view"; + private static int PARTICLES_COUNT = 12000; int mWidth; int mHeight; int mLoops; @@ -82,6 +88,7 @@ public class RsBenchRS { private Sampler mLinearWrap; private Sampler mMipLinearWrap; private Sampler mNearestClamp; + private Sampler mNearesWrap; private ProgramStore mProgStoreBlendNoneDepth; private ProgramStore mProgStoreBlendNone; @@ -106,6 +113,7 @@ public class RsBenchRS { private ScriptField_VertexShaderConstants3_s mVSConstPixel; private ScriptField_FragentShaderConstants3_s mFSConstPixel; + private ProgramRaster mCullBack; private ProgramRaster mCullFront; private ProgramRaster mCullNone; @@ -121,6 +129,7 @@ public class RsBenchRS { private Mesh mWbyHMesh; private Mesh mTorus; private Mesh mSingleMesh; + private Mesh mParticlesMesh; Font mFontSans; Font mFontSerif; @@ -128,6 +137,9 @@ public class RsBenchRS { private ScriptField_ListAllocs_s mTextureAllocs; private ScriptField_ListAllocs_s mSampleTextAllocs; + private ScriptField_ListAllocs_s mSampleListViewAllocs; + private ScriptField_VpConsts mPvStarAlloc; + private ScriptC_rsbench mScript; @@ -300,6 +312,15 @@ public class RsBenchRS { mScript.set_gProgStoreBlendNone(mProgStoreBlendNone); mScript.set_gProgStoreBlendAlpha(mProgStoreBlendAlpha); mScript.set_gProgStoreBlendAdd(mProgStoreBlendAdd); + + // For GALAXY + builder = new ProgramStore.Builder(mRS); + builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO); + mRS.bindProgramStore(builder.create()); + + builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE); + mScript.set_gPSLights(builder.create()); + } private void initProgramFragment() { @@ -316,8 +337,59 @@ public class RsBenchRS { mScript.set_gProgFragmentColor(mProgFragmentColor); mScript.set_gProgFragmentTexture(mProgFragmentTexture); + + + // For Galaxy live wallpaper drawing + ProgramFragmentFixedFunction.Builder builder = new ProgramFragmentFixedFunction.Builder(mRS); + builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE, + ProgramFragmentFixedFunction.Builder.Format.RGB, 0); + ProgramFragment pfb = builder.create(); + pfb.bindSampler(mNearesWrap, 0); + mScript.set_gPFBackground(pfb); + + builder = new ProgramFragmentFixedFunction.Builder(mRS); + builder.setPointSpriteTexCoordinateReplacement(true); + builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.MODULATE, + ProgramFragmentFixedFunction.Builder.Format.RGBA, 0); + builder.setVaryingColor(true); + ProgramFragment pfs = builder.create(); + pfs.bindSampler(mMipLinearWrap, 0); + mScript.set_gPFStars(pfs); + } + private Matrix4f getProjectionNormalized(int w, int h) { + // range -1,1 in the narrow axis at z = 0. + Matrix4f m1 = new Matrix4f(); + Matrix4f m2 = new Matrix4f(); + + if(w > h) { + float aspect = ((float)w) / h; + m1.loadFrustum(-aspect,aspect, -1,1, 1,100); + } else { + float aspect = ((float)h) / w; + m1.loadFrustum(-1,1, -aspect,aspect, 1,100); + } + + m2.loadRotate(180, 0, 1, 0); + m1.loadMultiply(m1, m2); + + m2.loadScale(-2, 2, 1); + m1.loadMultiply(m1, m2); + + m2.loadTranslate(0, 0, 2); + m1.loadMultiply(m1, m2); + return m1; + } + + private void updateProjectionMatrices() { + Matrix4f projNorm = getProjectionNormalized(mBenchmarkDimX, mBenchmarkDimY); + ScriptField_VpConsts.Item i = new ScriptField_VpConsts.Item(); + i.Proj = projNorm; + i.MVP = projNorm; + mPvStarAlloc.set(i, 0, true); + } + private void initProgramVertex() { ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS); mProgVertex = pvb.create(); @@ -329,6 +401,39 @@ public class RsBenchRS { mPVA.setProjection(proj); mScript.set_gProgVertex(mProgVertex); + + // For galaxy live wallpaper + mPvStarAlloc = new ScriptField_VpConsts(mRS, 1); + mScript.bind_vpConstants(mPvStarAlloc); + updateProjectionMatrices(); + + ProgramVertex.Builder sb = new ProgramVertex.Builder(mRS); + String t = "varying vec4 varColor;\n" + + "varying vec2 varTex0;\n" + + "void main() {\n" + + " float dist = ATTRIB_position.y;\n" + + " float angle = ATTRIB_position.x;\n" + + " float x = dist * sin(angle);\n" + + " float y = dist * cos(angle) * 0.892;\n" + + " float p = dist * 5.5;\n" + + " float s = cos(p);\n" + + " float t = sin(p);\n" + + " vec4 pos;\n" + + " pos.x = t * x + s * y;\n" + + " pos.y = s * x - t * y;\n" + + " pos.z = ATTRIB_position.z;\n" + + " pos.w = 1.0;\n" + + " gl_Position = UNI_MVP * pos;\n" + + " gl_PointSize = ATTRIB_color.a * 10.0;\n" + + " varColor.rgb = ATTRIB_color.rgb;\n" + + " varColor.a = 1.0;\n" + + "}\n"; + sb.setShader(t); + sb.addInput(mParticlesMesh.getVertexAllocation(0).getType().getElement()); + sb.addConstant(mPvStarAlloc.getType()); + ProgramVertex pvs = sb.create(); + pvs.bindConstants(mPvStarAlloc.getAllocation(), 0); + mScript.set_gPVStars(pvs); } private void initCustomShaders() { @@ -426,6 +531,11 @@ public class RsBenchRS { mScript.set_gTexTransparent(mTexTransparent); mScript.set_gTexChecker(mTexChecker); mScript.set_gTexGlobe(mTexGlobe); + + // For Galaxy live wallpaper + mScript.set_gTSpace(loadTextureRGB(R.drawable.space)); + mScript.set_gTLight1(loadTextureRGB(R.drawable.light1)); + mScript.set_gTFlares(loadTextureARGB(R.drawable.flares)); } private void initFonts() { @@ -440,6 +550,19 @@ public class RsBenchRS { mScript.set_gFontSerif(mFontSerif); } + private void createParticlesMesh() { + ScriptField_Particle p = new ScriptField_Particle(mRS, PARTICLES_COUNT); + + final Mesh.AllocationBuilder meshBuilder = new Mesh.AllocationBuilder(mRS); + meshBuilder.addVertexAllocation(p.getAllocation()); + final int vertexSlot = meshBuilder.getCurrentVertexTypeIndex(); + meshBuilder.addIndexSetType(Primitive.POINT); + mParticlesMesh = meshBuilder.create(); + + mScript.set_gParticlesMesh(mParticlesMesh); + mScript.bind_Particles(p); + } + private void initMesh() { m10by10Mesh = getMbyNMesh(mBenchmarkDimX, mBenchmarkDimY, 10, 10); mScript.set_g10by10Mesh(m10by10Mesh); @@ -458,6 +581,8 @@ public class RsBenchRS { mTorus = (Mesh)entry.getObject(); mScript.set_gTorusMesh(mTorus); } + + createParticlesMesh(); } private void initSamplers() { @@ -471,6 +596,7 @@ public class RsBenchRS { mLinearClamp = Sampler.CLAMP_LINEAR(mRS); mNearestClamp = Sampler.CLAMP_NEAREST(mRS); mMipLinearWrap = Sampler.WRAP_LINEAR_MIP_LINEAR(mRS); + mNearesWrap = Sampler.WRAP_NEAREST(mRS); mScript.set_gLinearClamp(mLinearClamp); mScript.set_gLinearWrap(mLinearWrap); @@ -524,10 +650,10 @@ public class RsBenchRS { initSamplers(); initProgramStore(); initProgramFragment(); + initMesh(); initProgramVertex(); initFonts(); loadImages(); - initMesh(); initProgramRaster(); initCustomShaders(); @@ -567,6 +693,15 @@ public class RsBenchRS { mSampleTextAllocs.copyAll(); mScript.bind_gSampleTextList100(mSampleTextAllocs); + mSampleListViewAllocs = new ScriptField_ListAllocs_s(mRS, 1000); + for (int i = 0; i < 1000; i++) { + ScriptField_ListAllocs_s.Item textElem = new ScriptField_ListAllocs_s.Item(); + textElem.item = Allocation.createFromString(mRS, LIST_TEXT, Allocation.USAGE_SCRIPT); + mSampleListViewAllocs.set(textElem, i, false); + } + mSampleListViewAllocs.copyAll(); + mScript.bind_gListViewText(mSampleListViewAllocs); + mRS.bindRootScript(mScript); } } diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs index 0294b31..6d80b0e 100644 --- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs +++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs @@ -23,9 +23,50 @@ const int RS_MSG_TEST_DONE = 100; const int RS_MSG_RESULTS_READY = 101; -const int gMaxModes = 29; +const int gMaxModes = 31; int gMaxLoops; +// Parameters for galaxy live wallpaper +rs_allocation gTSpace; +rs_allocation gTLight1; +rs_allocation gTFlares; +rs_mesh gParticlesMesh; + +rs_program_fragment gPFBackground; +rs_program_fragment gPFStars; +rs_program_vertex gPVStars; +rs_program_vertex gPVBkProj; +rs_program_store gPSLights; + +float gXOffset = 0.5f; + +#define ELLIPSE_RATIO 0.892f +#define PI 3.1415f +#define TWO_PI 6.283f +#define ELLIPSE_TWIST 0.023333333f + +static float angle = 50.f; +static int gOldWidth; +static int gOldHeight; +static int gWidth; +static int gHeight; +static float gSpeed[12000]; +static int gGalaxyRadius = 300; +static rs_allocation gParticlesBuffer; + +typedef struct __attribute__((packed, aligned(4))) Particle { + uchar4 color; + float3 position; +} Particle_t; +Particle_t *Particles; + +typedef struct VpConsts { + rs_matrix4x4 Proj; + rs_matrix4x4 MVP; +} VpConsts_t; +VpConsts_t *vpConstants; +// End of parameters for galaxy live wallpaper + // Allocation to send test names back to java char *gStringBuffer = 0; // Allocation to write the results into @@ -52,6 +93,7 @@ typedef struct ListAllocs_s { ListAllocs *gTexList100; ListAllocs *gSampleTextList100; +ListAllocs *gListViewText; rs_mesh g10by10Mesh; rs_mesh g100by100Mesh; @@ -109,6 +151,141 @@ static float textColors[] = {1.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.6f, 0.7f, 1.0f, }; +/** + * Methods to draw the galaxy live wall paper + */ +static float mapf(float minStart, float minStop, float maxStart, float maxStop, float value) { + return maxStart + (maxStart - maxStop) * ((value - minStart) / (minStop - minStart)); +} + +/** + * Helper function to generate the stars. + */ +static float randomGauss() { + float x1; + float x2; + float w = 2.f; + + while (w >= 1.0f) { + x1 = rsRand(2.0f) - 1.0f; + x2 = rsRand(2.0f) - 1.0f; + w = x1 * x1 + x2 * x2; + } + + w = sqrt(-2.0f * log(w) / w); + return x1 * w; +} + +/** + * Generates the properties for a given star. + */ +static void createParticle(Particle_t *part, int idx, float scale) { + float d = fabs(randomGauss()) * gGalaxyRadius * 0.5f + rsRand(64.0f); + float id = d / gGalaxyRadius; + float z = randomGauss() * 0.4f * (1.0f - id); + float p = -d * ELLIPSE_TWIST; + + if (d < gGalaxyRadius * 0.33f) { + part->color.x = (uchar) (220 + id * 35); + part->color.y = 220; + part->color.z = 220; + } else { + part->color.x = 180; + part->color.y = 180; + part->color.z = (uchar) clamp(140.f + id * 115.f, 140.f, 255.f); + } + // Stash point size * 10 in Alpha + part->color.w = (uchar) (rsRand(1.2f, 2.1f) * 60); + + if (d > gGalaxyRadius * 0.15f) { + z *= 0.6f * (1.0f - id); + } else { + z *= 0.72f; + } + + // Map to the projection coordinates (viewport.x = -1.0 -> 1.0) + d = mapf(-4.0f, gGalaxyRadius + 4.0f, 0.0f, scale, d); + + part->position.x = rsRand(TWO_PI); + part->position.y = d; + gSpeed[idx] = rsRand(0.0015f, 0.0025f) * (0.5f + (scale / d)) * 0.8f; + + part->position.z = z / 5.0f; +} + +/** + * Initialize all the starts, called from Java + */ +void initParticles() { + Particle_t *part = Particles; + float scale = gGalaxyRadius / (gWidth * 0.5f); + int count = rsAllocationGetDimX(gParticlesBuffer); + for (int i = 0; i < count; i ++) { + createParticle(part, i, scale); + part++; + } +} + +static void drawSpace() { + rsgBindProgramFragment(gPFBackground); + rsgBindTexture(gPFBackground, 0, gTSpace); + rsgDrawQuadTexCoords( + 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, + gWidth, 0.0f, 0.0f, 2.0f, 1.0f, + gWidth, gHeight, 0.0f, 2.0f, 0.0f, + 0.0f, gHeight, 0.0f, 0.0f, 0.0f); +} + +static void drawLights() { + rsgBindProgramVertex(gPVBkProj); + rsgBindProgramFragment(gPFBackground); + rsgBindTexture(gPFBackground, 0, gTLight1); + + float scale = 512.0f / gWidth; + float x = -scale - scale * 0.05f; + float y = -scale; + + scale *= 2.0f; + + rsgDrawQuad(x, y, 0.0f, + x + scale * 1.1f, y, 0.0f, + x + scale * 1.1f, y + scale, 0.0f, + x, y + scale, 0.0f); +} + +static void drawParticles(float offset) { + float a = offset * angle; + float absoluteAngle = fabs(a); + + rs_matrix4x4 matrix; + rsMatrixLoadTranslate(&matrix, 0.0f, 0.0f, 10.0f - 6.0f * absoluteAngle / 50.0f); + if (gHeight > gWidth) { + rsMatrixScale(&matrix, 6.6f, 6.0f, 1.0f); + } else { + rsMatrixScale(&matrix, 12.6f, 12.0f, 1.0f); + } + rsMatrixRotate(&matrix, absoluteAngle, 1.0f, 0.0f, 0.0f); + rsMatrixRotate(&matrix, a, 0.0f, 0.4f, 0.1f); + rsMatrixLoad(&vpConstants->MVP, &vpConstants->Proj); + rsMatrixMultiply(&vpConstants->MVP, &matrix); + rsgAllocationSyncAll(rsGetAllocation(vpConstants)); + + rsgBindProgramVertex(gPVStars); + rsgBindProgramFragment(gPFStars); + rsgBindProgramStore(gPSLights); + rsgBindTexture(gPFStars, 0, gTFlares); + + Particle_t *vtx = Particles; + int count = rsAllocationGetDimX(gParticlesBuffer); + for (int i = 0; i < count; i++) { + vtx->position.x = vtx->position.x + gSpeed[i]; + vtx++; + } + + rsgDrawMesh(gParticlesMesh); +} +/* end of methods for drawing galaxy */ + static void setupOffscreenTarget() { rsgBindColorTarget(gRenderBufferColor, 0); rsgBindDepthTarget(gRenderBufferDepth); @@ -303,6 +480,71 @@ static void displayImageWithText(int wResolution, int hResolution, int meshMode) } } +// Display a list of text as the list view +static void displayListView() { + // set text color + rsgFontColor(0.9f, 0.9f, 0.9f, 1.0f); + rsgBindFont(gFontSans); + + // get the size of the list + rs_allocation textAlloc; + textAlloc = rsGetAllocation(gListViewText); + int allocSize = rsAllocationGetDimX(textAlloc); + + int listItemHeight = 80; + int yOffset = listItemHeight; + + // set the color for the list divider + rsgBindProgramFragment(gProgFragmentColor); + rsgProgramFragmentConstantColor(gProgFragmentColor, 1.0, 1.0, 1.0, 1); + + // draw the list with divider + for (int i = 0; i < allocSize; i++) { + if (yOffset - listItemHeight > gRenderSurfaceH) { + break; + } + rsgDrawRect(0, yOffset - 1, gRenderSurfaceW, yOffset, 0); + rsgDrawText(gListViewText[i].item, 20, yOffset - 10); + yOffset += listItemHeight; + } +} + +static void drawGalaxy() { + rsgClearColor(0.f, 0.f, 0.f, 1.f); + gParticlesBuffer = rsGetAllocation(Particles); + rsgBindProgramFragment(gPFBackground); + + gWidth = rsgGetWidth(); + gHeight = rsgGetHeight(); + if ((gWidth != gOldWidth) || (gHeight != gOldHeight)) { + initParticles(); + gOldWidth = gWidth; + gOldHeight = gHeight; + } + + float offset = mix(-1.0f, 1.0f, gXOffset); + drawSpace(); + drawParticles(offset); + drawLights(); +} + +// Display images and text with live wallpaper in the background +static void dispalyLiveWallPaper(int wResolution, int hResolution) { + bindProgramVertexOrtho(); + + drawGalaxy(); + + rsgBindProgramStore(gProgStoreBlendAlpha); + rsgBindProgramFragment(gProgFragmentTexture); + rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp); + + drawMeshInPage(0, 0, wResolution, hResolution); + drawMeshInPage(-1.0f*gRenderSurfaceW, 0, wResolution, hResolution); + drawMeshInPage(1.0f*gRenderSurfaceW, 0, wResolution, hResolution); + drawMeshInPage(-2.0f*gRenderSurfaceW, 0, wResolution, hResolution); + drawMeshInPage(2.0f*gRenderSurfaceW, 0, wResolution, hResolution); +} + static float gTorusRotation = 0; static void updateModelMatrix(rs_matrix4x4 *matrix, void *buffer) { if (buffer == 0) { @@ -602,14 +844,12 @@ static const char *testNames[] = { "Geo test 25.6k heavy fragment heavy vertex", "Geo test 51.2k heavy fragment heavy vertex", "Geo test 204.8k small tries heavy fragment heavy vertex", - "UI test with icon display 10 by 10", // 25 - "UI test with icon display 100 by 100", // 26 - "UI test with image and text display 3 pages", // 27 - "UI test with image and text display 5 pages", // 28 - "UI test with list view", // 29 -// "UI test with live wallpaper", // 30 -// "Mesh with 10 by 10 texture", -// "Mesh with 100 by 100 texture", + "UI test with icon display 10 by 10", + "UI test with icon display 100 by 100", + "UI test with image and text display 3 pages", + "UI test with image and text display 5 pages", + "UI test with list view", + "UI test with live wallpaper", }; void getTestName(int testIndex) { @@ -714,6 +954,12 @@ static void runTest(int index) { case 28: displayImageWithText(7, 5, 1); break; + case 29: + displayListView(); + break; + case 30: + dispalyLiveWallPaper(7, 5); + break; } } @@ -737,7 +983,6 @@ static void drawOffscreenResult(int posX, int posY, int width, int height) { } int root(void) { - gRenderSurfaceW = rsgGetWidth(); gRenderSurfaceH = rsgGetHeight(); rsgClearColor(0.2f, 0.2f, 0.2f, 1.0f); diff --git a/tests/StatusBar/res/drawable-hdpi/emo_im_kissing.png b/tests/StatusBar/res/drawable-hdpi/emo_im_kissing.png Binary files differnew file mode 100644 index 0000000..0a8f0d7 --- /dev/null +++ b/tests/StatusBar/res/drawable-hdpi/emo_im_kissing.png diff --git a/tests/StatusBar/res/drawable-hdpi/notification0.png b/tests/StatusBar/res/drawable-hdpi/notification0.png Binary files differnew file mode 100644 index 0000000..6d2612e --- /dev/null +++ b/tests/StatusBar/res/drawable-hdpi/notification0.png diff --git a/tests/StatusBar/res/drawable-hdpi/notification1.png b/tests/StatusBar/res/drawable-hdpi/notification1.png Binary files differnew file mode 100644 index 0000000..ce9009c --- /dev/null +++ b/tests/StatusBar/res/drawable-hdpi/notification1.png diff --git a/tests/StatusBar/res/drawable-hdpi/notification2.png b/tests/StatusBar/res/drawable-hdpi/notification2.png Binary files differnew file mode 100644 index 0000000..772d70a --- /dev/null +++ b/tests/StatusBar/res/drawable-hdpi/notification2.png diff --git a/tests/StatusBar/res/drawable-hdpi/notification3.png b/tests/StatusBar/res/drawable-hdpi/notification3.png Binary files differnew file mode 100644 index 0000000..61127ee --- /dev/null +++ b/tests/StatusBar/res/drawable-hdpi/notification3.png diff --git a/tests/StatusBar/res/drawable-hdpi/notification4.png b/tests/StatusBar/res/drawable-hdpi/notification4.png Binary files differnew file mode 100644 index 0000000..40b7d55 --- /dev/null +++ b/tests/StatusBar/res/drawable-hdpi/notification4.png diff --git a/tests/StatusBar/res/drawable-hdpi/notification5.png b/tests/StatusBar/res/drawable-hdpi/notification5.png Binary files differnew file mode 100644 index 0000000..e89903a --- /dev/null +++ b/tests/StatusBar/res/drawable-hdpi/notification5.png diff --git a/tests/StatusBar/res/drawable-hdpi/notification6.png b/tests/StatusBar/res/drawable-hdpi/notification6.png Binary files differnew file mode 100644 index 0000000..e0878f5 --- /dev/null +++ b/tests/StatusBar/res/drawable-hdpi/notification6.png diff --git a/tests/StatusBar/res/drawable-hdpi/notification7.png b/tests/StatusBar/res/drawable-hdpi/notification7.png Binary files differnew file mode 100644 index 0000000..49397ca --- /dev/null +++ b/tests/StatusBar/res/drawable-hdpi/notification7.png diff --git a/tests/StatusBar/res/drawable-hdpi/notification8.png b/tests/StatusBar/res/drawable-hdpi/notification8.png Binary files differnew file mode 100644 index 0000000..763b048 --- /dev/null +++ b/tests/StatusBar/res/drawable-hdpi/notification8.png diff --git a/tests/StatusBar/res/drawable-hdpi/notification9.png b/tests/StatusBar/res/drawable-hdpi/notification9.png Binary files differnew file mode 100644 index 0000000..c3c3771 --- /dev/null +++ b/tests/StatusBar/res/drawable-hdpi/notification9.png diff --git a/tests/StatusBar/res/drawable-hdpi/notificationx.png b/tests/StatusBar/res/drawable-hdpi/notificationx.png Binary files differnew file mode 100644 index 0000000..7267286 --- /dev/null +++ b/tests/StatusBar/res/drawable-hdpi/notificationx.png diff --git a/tests/StatusBar/res/drawable-hdpi/pineapple.png b/tests/StatusBar/res/drawable-hdpi/pineapple.png Binary files differnew file mode 100644 index 0000000..e62d3c8 --- /dev/null +++ b/tests/StatusBar/res/drawable-hdpi/pineapple.png diff --git a/tests/StatusBar/res/drawable-hdpi/pineapple2.png b/tests/StatusBar/res/drawable-hdpi/pineapple2.png Binary files differnew file mode 100644 index 0000000..54146a8 --- /dev/null +++ b/tests/StatusBar/res/drawable-hdpi/pineapple2.png diff --git a/tests/StatusBar/res/layout/notification_builder_test.xml b/tests/StatusBar/res/layout/notification_builder_test.xml index 3c37a73..e1199c7 100644 --- a/tests/StatusBar/res/layout/notification_builder_test.xml +++ b/tests/StatusBar/res/layout/notification_builder_test.xml @@ -1,224 +1,220 @@ <?xml version="1.0" encoding="utf-8"?> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" +<ScrollView android:layout_width="match_parent" android:layout_height="match_parent" - android:orientation="horizontal" - android:paddingLeft="40dp" - android:paddingTop="12dp" - android:paddingRight="24dp" - android:paddingBottom="12dp" + xmlns:android="http://schemas.android.com/apk/res/android" > - <LinearLayout - android:layout_width="220sp" + android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_marginRight="24dp" - android:orientation="vertical" + android:orientation="horizontal" > + <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" - > - <Button - style="@style/IdButton.Minus" - android:id="@+id/clear_1" - /> - <TextView - style="@style/IdTitle" - android:text="1" - /> - <Button - style="@style/IdButton.Plus" - android:id="@+id/notify_1" - /> - </LinearLayout> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" - > - <Button - style="@style/IdButton.Minus" - android:id="@+id/clear_2" - /> - <TextView - style="@style/IdTitle" - android:text="2" - /> - <Button - style="@style/IdButton.Plus" - android:id="@+id/notify_2" - /> - </LinearLayout> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" - > - <Button - style="@style/IdButton.Minus" - android:id="@+id/clear_3" - /> - <TextView - style="@style/IdTitle" - android:text="3" - /> - <Button - style="@style/IdButton.Plus" - android:id="@+id/notify_3" - /> - </LinearLayout> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" - > - <Button - style="@style/IdButton.Minus" - android:id="@+id/clear_4" - /> - <TextView - style="@style/IdTitle" - android:text="4" - /> - <Button - style="@style/IdButton.Plus" - android:id="@+id/notify_4" - /> - </LinearLayout> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" - > - <Button - style="@style/IdButton.Minus" - android:id="@+id/clear_5" - /> - <TextView - style="@style/IdTitle" - android:text="5" - /> - <Button - style="@style/IdButton.Plus" - android:id="@+id/notify_5" - /> - </LinearLayout> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" - > - <Button - style="@style/IdButton.Minus" - android:id="@+id/clear_6" - /> - <TextView - style="@style/IdTitle" - android:text="6" - /> - <Button - style="@style/IdButton.Plus" - android:id="@+id/notify_6" - /> - </LinearLayout> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" - > - <Button - style="@style/IdButton.Minus" - android:id="@+id/clear_7" - /> - <TextView - style="@style/IdTitle" - android:text="7" - /> - <Button - style="@style/IdButton.Plus" - android:id="@+id/notify_7" - /> - </LinearLayout> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" - > - <Button - style="@style/IdButton.Minus" - android:id="@+id/clear_8" - /> - <TextView - style="@style/IdTitle" - android:text="8" - /> - <Button - style="@style/IdButton.Plus" - android:id="@+id/notify_8" - /> - </LinearLayout> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" - > - <Button - style="@style/IdButton.Minus" - android:id="@+id/clear_9" - /> - <TextView - style="@style/IdTitle" - android:text="9" - /> - <Button - style="@style/IdButton.Plus" - android:id="@+id/notify_9" - /> - </LinearLayout> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" + android:layout_width="120dp" + android:layout_height="match_parent" + android:orientation="vertical" > + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + > + <Button + style="@style/IdButton.Minus" + android:id="@+id/clear_1" + /> + <TextView + style="@style/IdTitle" + android:text="1" + /> + <Button + style="@style/IdButton.Plus" + android:id="@+id/notify_1" + /> + </LinearLayout> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + > + <Button + style="@style/IdButton.Minus" + android:id="@+id/clear_2" + /> + <TextView + style="@style/IdTitle" + android:text="2" + /> + <Button + style="@style/IdButton.Plus" + android:id="@+id/notify_2" + /> + </LinearLayout> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + > + <Button + style="@style/IdButton.Minus" + android:id="@+id/clear_3" + /> + <TextView + style="@style/IdTitle" + android:text="3" + /> + <Button + style="@style/IdButton.Plus" + android:id="@+id/notify_3" + /> + </LinearLayout> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + > + <Button + style="@style/IdButton.Minus" + android:id="@+id/clear_4" + /> + <TextView + style="@style/IdTitle" + android:text="4" + /> + <Button + style="@style/IdButton.Plus" + android:id="@+id/notify_4" + /> + </LinearLayout> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + > + <Button + style="@style/IdButton.Minus" + android:id="@+id/clear_5" + /> + <TextView + style="@style/IdTitle" + android:text="5" + /> + <Button + style="@style/IdButton.Plus" + android:id="@+id/notify_5" + /> + </LinearLayout> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + > + <Button + style="@style/IdButton.Minus" + android:id="@+id/clear_6" + /> + <TextView + style="@style/IdTitle" + android:text="6" + /> + <Button + style="@style/IdButton.Plus" + android:id="@+id/notify_6" + /> + </LinearLayout> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + > + <Button + style="@style/IdButton.Minus" + android:id="@+id/clear_7" + /> + <TextView + style="@style/IdTitle" + android:text="7" + /> + <Button + style="@style/IdButton.Plus" + android:id="@+id/notify_7" + /> + </LinearLayout> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + > + <Button + style="@style/IdButton.Minus" + android:id="@+id/clear_8" + /> + <TextView + style="@style/IdTitle" + android:text="8" + /> + <Button + style="@style/IdButton.Plus" + android:id="@+id/notify_8" + /> + </LinearLayout> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + > + <Button + style="@style/IdButton.Minus" + android:id="@+id/clear_9" + /> + <TextView + style="@style/IdTitle" + android:text="9" + /> + <Button + style="@style/IdButton.Plus" + android:id="@+id/notify_9" + /> + </LinearLayout> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + > + <Button + style="@style/IdButton.Minus" + android:id="@+id/clear_10" + /> + <TextView + style="@style/IdTitle" + android:text="10" + /> + <Button + style="@style/IdButton.Plus" + android:id="@+id/notify_10" + /> + </LinearLayout> + <Button - style="@style/IdButton.Minus" - android:id="@+id/clear_10" - /> - <TextView - style="@style/IdTitle" - android:text="10" + android:id="@+id/clear_all" + android:textAppearance="?android:attr/textAppearanceSmall" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="12dp" + android:layout_marginBottom="12dp" + android:text="Clear All" /> <Button - style="@style/IdButton.Plus" - android:id="@+id/notify_10" + android:id="@+id/ten" + android:textAppearance="?android:attr/textAppearanceSmall" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="Ten notifications" /> + </LinearLayout> - <Button - android:id="@+id/clear_all" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="12dp" - android:layout_marginBottom="12dp" - android:text="Clear All" - /> - <Button - android:id="@+id/ten" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:text="Ten notifications" - /> - - </LinearLayout> - - <ScrollView - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:layout_weight="1" - > <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" @@ -818,7 +814,6 @@ </LinearLayout> - </ScrollView> - + </LinearLayout> -</LinearLayout> +</ScrollView> diff --git a/tests/StatusBar/res/values-sw600dp/styles.xml b/tests/StatusBar/res/values-sw600dp/styles.xml new file mode 100644 index 0000000..f29847c --- /dev/null +++ b/tests/StatusBar/res/values-sw600dp/styles.xml @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2011 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. +--> +<resources> + <style name="IdTitle"> + <item name="android:textAppearance">?android:attr/textAppearanceLarge</item> + <item name="android:layout_width">30sp</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:gravity">center</item> + <item name="android:textStyle">bold</item> + </style> + + <style name="IdButton"> + <item name="android:textAppearance">?android:attr/textAppearanceLarge</item> + <item name="android:layout_width">0dp</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:layout_weight">1</item> + <item name="android:layout_marginRight">8dp</item> + <item name="android:layout_marginLeft">8dp</item> + <item name="android:textStyle">bold</item> + </style> + + <style name="IdButton.Minus"> + <item name="android:text">-</item> + </style> + + <style name="IdButton.Plus"> + <item name="android:text">+</item> + </style> + + <style name="FieldTitle"> + <item name="android:textAppearance">?android:attr/textAppearanceLarge</item> + <item name="android:layout_width">208sp</item> + <item name="android:layout_height">wrap_content</item> + </style> + + <style name="FieldContents"> + <item name="android:textAppearance">?android:attr/textAppearanceMedium</item> + <item name="android:layout_width">wrap_content</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:layout_marginRight">20dp</item> + </style> + + <style name="FieldContents.Disabled"> + <item name="android:clickable">false</item> + <item name="android:visibility">gone</item> + </style> + +</resources> + + diff --git a/tests/StatusBar/res/values/styles.xml b/tests/StatusBar/res/values/styles.xml index e051efd..103a25a 100644 --- a/tests/StatusBar/res/values/styles.xml +++ b/tests/StatusBar/res/values/styles.xml @@ -16,21 +16,23 @@ <resources> <style name="IdTitle"> - <item name="android:textAppearance">?android:attr/textAppearanceLarge</item> - <item name="android:layout_width">30sp</item> + <item name="android:textAppearance">?android:attr/textAppearanceSmall</item> + <item name="android:layout_width">20sp</item> <item name="android:layout_height">wrap_content</item> <item name="android:gravity">center</item> <item name="android:textStyle">bold</item> </style> <style name="IdButton"> - <item name="android:textAppearance">?android:attr/textAppearanceLarge</item> - <item name="android:layout_width">0dp</item> + <item name="android:textAppearance">?android:attr/textAppearanceMedium</item> + <item name="android:layout_width">10dp</item> <item name="android:layout_height">wrap_content</item> <item name="android:layout_weight">1</item> - <item name="android:layout_marginRight">8dp</item> - <item name="android:layout_marginLeft">8dp</item> <item name="android:textStyle">bold</item> + <item name="android:layout_marginLeft">1dp</item> + <item name="android:layout_marginRight">1dp</item> + <item name="android:paddingLeft">6dp</item> + <item name="android:paddingRight">6dp</item> </style> <style name="IdButton.Minus"> @@ -42,16 +44,16 @@ </style> <style name="FieldTitle"> - <item name="android:textAppearance">?android:attr/textAppearanceLarge</item> - <item name="android:layout_width">208sp</item> + <item name="android:textAppearance">?android:attr/textAppearanceSmall</item> + <item name="android:layout_width">wrap_content</item> <item name="android:layout_height">wrap_content</item> </style> <style name="FieldContents"> - <item name="android:textAppearance">?android:attr/textAppearanceMedium</item> + <item name="android:textAppearance">?android:attr/textAppearanceSmall</item> <item name="android:layout_width">wrap_content</item> <item name="android:layout_height">wrap_content</item> - <item name="android:layout_marginRight">20dp</item> + <item name="android:layout_marginRight">4dp</item> </style> <style name="FieldContents.Disabled"> diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp index 223b1fa..7852197 100644 --- a/tools/aapt/Command.cpp +++ b/tools/aapt/Command.cpp @@ -291,6 +291,27 @@ static int32_t getIntegerAttribute(const ResXMLTree& tree, uint32_t attrRes, return value.data; } +static int32_t getResolvedIntegerAttribute(const ResTable* resTable, const ResXMLTree& tree, + uint32_t attrRes, String8* outError, int32_t defValue = -1) +{ + ssize_t idx = indexOfAttribute(tree, attrRes); + if (idx < 0) { + return defValue; + } + Res_value value; + if (tree.getAttributeValue(idx, &value) != NO_ERROR) { + if (value.dataType == Res_value::TYPE_REFERENCE) { + resTable->resolveReference(&value, 0); + } + if (value.dataType < Res_value::TYPE_FIRST_INT + || value.dataType > Res_value::TYPE_LAST_INT) { + if (outError != NULL) *outError = "attribute is not an integer value"; + return defValue; + } + } + return value.data; +} + static String8 getResolvedAttribute(const ResTable* resTable, const ResXMLTree& tree, uint32_t attrRes, String8* outError) { @@ -320,11 +341,12 @@ static String8 getResolvedAttribute(const ResTable* resTable, const ResXMLTree& // These are attribute resource constants for the platform, as found // in android.R.attr enum { + LABEL_ATTR = 0x01010001, + ICON_ATTR = 0x01010002, NAME_ATTR = 0x01010003, VERSION_CODE_ATTR = 0x0101021b, VERSION_NAME_ATTR = 0x0101021c, - LABEL_ATTR = 0x01010001, - ICON_ATTR = 0x01010002, + SCREEN_ORIENTATION_ATTR = 0x0101001e, MIN_SDK_VERSION_ATTR = 0x0101020c, MAX_SDK_VERSION_ATTR = 0x01010271, REQ_TOUCH_SCREEN_ATTR = 0x01010227, @@ -634,6 +656,8 @@ int doDump(Bundle* bundle) bool reqDistinctMultitouchFeature = false; bool specScreenPortraitFeature = false; bool specScreenLandscapeFeature = false; + bool reqScreenPortraitFeature = false; + bool reqScreenLandscapeFeature = false; // 2.2 also added some other features that apps can request, but that // have no corresponding permission, so we cannot implement any // back-compatibility heuristic for them. The below are thus unnecessary @@ -1022,6 +1046,18 @@ int doDump(Bundle* bundle) fprintf(stderr, "ERROR getting 'android:icon' attribute: %s\n", error.string()); goto bail; } + + int32_t orien = getResolvedIntegerAttribute(&res, tree, + SCREEN_ORIENTATION_ATTR, &error); + if (error == "") { + if (orien == 0 || orien == 6 || orien == 8) { + // Requests landscape, sensorLandscape, or reverseLandscape. + reqScreenLandscapeFeature = true; + } else if (orien == 1 || orien == 7 || orien == 9) { + // Requests portrait, sensorPortrait, or reversePortrait. + reqScreenPortraitFeature = true; + } + } } else if (tag == "uses-library") { String8 libraryName = getAttribute(tree, NAME_ATTR, &error); if (error != "") { @@ -1182,12 +1218,16 @@ int doDump(Bundle* bundle) } // Landscape/portrait-related compatibility logic - if (!specScreenLandscapeFeature && !specScreenPortraitFeature && (targetSdk < 13)) { - // If app has not specified whether it requires portrait or landscape - // and is targeting an API before Honeycomb MR2, then assume it requires - // both. - printf("uses-feature:'android.hardware.screen.portrait'\n"); - printf("uses-feature:'android.hardware.screen.landscape'\n"); + if (!specScreenLandscapeFeature && !specScreenPortraitFeature) { + // If the app has specified any activities in its manifest + // that request a specific orientation, then assume that + // orientation is required. + if (reqScreenLandscapeFeature) { + printf("uses-feature:'android.hardware.screen.landscape'\n"); + } + if (reqScreenPortraitFeature) { + printf("uses-feature:'android.hardware.screen.portrait'\n"); + } } if (hasMainActivity) { diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java index 7380fc1..47fa68e 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java @@ -25,11 +25,11 @@ import com.android.ide.common.rendering.api.ResourceValue; import com.android.ide.common.rendering.api.StyleResourceValue; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.BridgeConstants; +import com.android.layoutlib.bridge.impl.ParserFactory; import com.android.layoutlib.bridge.impl.Stack; import com.android.resources.ResourceType; import com.android.util.Pair; -import org.kxml2.io.KXmlParser; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -206,6 +206,9 @@ public final class BridgeContext extends Activity { * @param parser the parser to add. */ public void pushParser(BridgeXmlBlockParser parser) { + if (ParserFactory.LOG_PARSER) { + System.out.println("PUSH " + parser.getParser().toString()); + } mParserStack.push(parser); } @@ -213,7 +216,10 @@ public final class BridgeContext extends Activity { * Removes the parser at the top of the stack */ public void popParser() { - mParserStack.pop(); + BridgeXmlBlockParser parser = mParserStack.pop(); + if (ParserFactory.LOG_PARSER) { + System.out.println("POPD " + parser.getParser().toString()); + } } /** @@ -346,9 +352,7 @@ public final class BridgeContext extends Activity { // we need to create a pull parser around the layout XML file, and then // give that to our XmlBlockParser try { - KXmlParser parser = new KXmlParser(); - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); - parser.setInput(new FileInputStream(xml), "UTF-8"); //$NON-NLS-1$); + XmlPullParser parser = ParserFactory.create(xml); // set the resource ref to have correct view cookies mBridgeInflater.setResourceReference(resource); @@ -687,25 +691,25 @@ public final class BridgeContext extends Activity { */ private BridgeTypedArray createStyleBasedTypedArray(StyleResourceValue style, int[] attrs) throws Resources.NotFoundException { - AtomicBoolean frameworkAttributes = new AtomicBoolean(); - AtomicReference<String> attrName = new AtomicReference<String>(); - TreeMap<Integer, String> styleNameMap = searchAttrs(attrs, frameworkAttributes, attrName); BridgeTypedArray ta = ((BridgeResources) mSystemResources).newTypeArray(attrs.length, - style.isFramework(), frameworkAttributes.get(), attrName.get()); - - // loop through all the values in the style map, and init the TypedArray with - // the style we got from the dynamic id - for (Entry<Integer, String> styleAttribute : styleNameMap.entrySet()) { - int index = styleAttribute.getKey().intValue(); + false, true, null); - String name = styleAttribute.getValue(); + // for each attribute, get its name so that we can search it in the style + for (int i = 0 ; i < attrs.length ; i++) { + Pair<ResourceType, String> resolvedResource = Bridge.resolveResourceId(attrs[i]); + if (resolvedResource != null) { + String attrName = resolvedResource.getSecond(); + // look for the value in the given style + ResourceValue resValue = mRenderResources.findItemInStyle(style, attrName); - // get the value from the style, or its parent styles. - ResourceValue resValue = mRenderResources.findItemInStyle(style, name); + if (resValue != null) { + // resolve it to make sure there are no references left. + ta.bridgeSetValue(i, attrName, mRenderResources.resolveResValue(resValue)); - // resolve it to make sure there are no references left. - ta.bridgeSetValue(index, name, mRenderResources.resolveResValue(resValue)); + resValue = mRenderResources.resolveResValue(resValue); + } + } } ta.sealArray(); diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java index 7c90a31..4a6393d 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java @@ -22,10 +22,10 @@ import com.android.ide.common.rendering.api.MergeCookie; import com.android.ide.common.rendering.api.ResourceReference; import com.android.ide.common.rendering.api.ResourceValue; import com.android.layoutlib.bridge.Bridge; +import com.android.layoutlib.bridge.impl.ParserFactory; import com.android.resources.ResourceType; import com.android.util.Pair; -import org.kxml2.io.KXmlParser; import org.xmlpull.v1.XmlPullParser; import android.content.Context; @@ -36,7 +36,6 @@ import android.view.View; import android.view.ViewGroup; import java.io.File; -import java.io.FileInputStream; /** * Custom implementation of {@link LayoutInflater} to handle custom views. @@ -175,9 +174,7 @@ public final class BridgeInflater extends LayoutInflater { File f = new File(value.getValue()); if (f.isFile()) { try { - KXmlParser parser = new KXmlParser(); - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); - parser.setInput(new FileInputStream(f), "UTF-8"); //$NON-NLS-1$ + XmlPullParser parser = ParserFactory.create(f); BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser( parser, bridgeContext, false); diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java index d0b90fb..1756496 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java @@ -21,12 +21,12 @@ import com.android.ide.common.rendering.api.LayoutLog; import com.android.ide.common.rendering.api.ResourceValue; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.BridgeConstants; +import com.android.layoutlib.bridge.impl.ParserFactory; import com.android.layoutlib.bridge.impl.ResourceHelper; import com.android.ninepatch.NinePatch; import com.android.resources.ResourceType; import com.android.util.Pair; -import org.kxml2.io.KXmlParser; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -131,14 +131,16 @@ public final class BridgeResources extends Resources { platformStyleable, styleableName); } - private ResourceValue getResourceValue(int id, boolean[] platformResFlag_out) { + private Pair<String, ResourceValue> getResourceValue(int id, boolean[] platformResFlag_out) { // first get the String related to this id in the framework Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(id); if (resourceInfo != null) { platformResFlag_out[0] = true; - return mContext.getRenderResources().getFrameworkResource( - resourceInfo.getFirst(), resourceInfo.getSecond()); + String attributeName = resourceInfo.getSecond(); + + return Pair.of(attributeName, mContext.getRenderResources().getFrameworkResource( + resourceInfo.getFirst(), attributeName)); } // didn't find a match in the framework? look in the project. @@ -147,8 +149,10 @@ public final class BridgeResources extends Resources { if (resourceInfo != null) { platformResFlag_out[0] = false; - return mContext.getRenderResources().getProjectResource( - resourceInfo.getFirst(), resourceInfo.getSecond()); + String attributeName = resourceInfo.getSecond(); + + return Pair.of(attributeName, mContext.getRenderResources().getProjectResource( + resourceInfo.getFirst(), attributeName)); } } @@ -157,10 +161,10 @@ public final class BridgeResources extends Resources { @Override public Drawable getDrawable(int id) throws NotFoundException { - ResourceValue value = getResourceValue(id, mPlatformResourceFlag); + Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag); if (value != null) { - return ResourceHelper.getDrawable(value, mContext); + return ResourceHelper.getDrawable(value.getSecond(), mContext); } // id was not found or not resolved. Throw a NotFoundException. @@ -172,11 +176,11 @@ public final class BridgeResources extends Resources { @Override public int getColor(int id) throws NotFoundException { - ResourceValue value = getResourceValue(id, mPlatformResourceFlag); + Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag); if (value != null) { try { - return ResourceHelper.getColor(value.getValue()); + return ResourceHelper.getColor(value.getSecond().getValue()); } catch (NumberFormatException e) { Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT, e.getMessage(), e, null /*data*/); @@ -193,10 +197,11 @@ public final class BridgeResources extends Resources { @Override public ColorStateList getColorStateList(int id) throws NotFoundException { - ResourceValue resValue = getResourceValue(id, mPlatformResourceFlag); + Pair<String, ResourceValue> resValue = getResourceValue(id, mPlatformResourceFlag); if (resValue != null) { - ColorStateList stateList = ResourceHelper.getColorStateList(resValue, mContext); + ColorStateList stateList = ResourceHelper.getColorStateList(resValue.getSecond(), + mContext); if (stateList != null) { return stateList; } @@ -211,10 +216,10 @@ public final class BridgeResources extends Resources { @Override public CharSequence getText(int id) throws NotFoundException { - ResourceValue value = getResourceValue(id, mPlatformResourceFlag); + Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag); if (value != null) { - return value.getValue(); + return value.getSecond().getValue(); } // id was not found or not resolved. Throw a NotFoundException. @@ -226,9 +231,10 @@ public final class BridgeResources extends Resources { @Override public XmlResourceParser getLayout(int id) throws NotFoundException { - ResourceValue value = getResourceValue(id, mPlatformResourceFlag); + Pair<String, ResourceValue> v = getResourceValue(id, mPlatformResourceFlag); - if (value != null) { + if (v != null) { + ResourceValue value = v.getSecond(); XmlPullParser parser = null; try { @@ -243,9 +249,7 @@ public final class BridgeResources extends Resources { if (xml.isFile()) { // we need to create a pull parser around the layout XML file, and then // give that to our XmlBlockParser - parser = new KXmlParser(); - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); - parser.setInput(new FileInputStream(xml), "UTF-8"); //$NON-NLS-1$); + parser = ParserFactory.create(xml); } } @@ -271,9 +275,10 @@ public final class BridgeResources extends Resources { @Override public XmlResourceParser getAnimation(int id) throws NotFoundException { - ResourceValue value = getResourceValue(id, mPlatformResourceFlag); + Pair<String, ResourceValue> v = getResourceValue(id, mPlatformResourceFlag); - if (value != null) { + if (v != null) { + ResourceValue value = v.getSecond(); XmlPullParser parser = null; try { @@ -281,9 +286,7 @@ public final class BridgeResources extends Resources { if (xml.isFile()) { // we need to create a pull parser around the layout XML file, and then // give that to our XmlBlockParser - parser = new KXmlParser(); - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); - parser.setInput(new FileInputStream(xml), "UTF-8"); //$NON-NLS-1$); + parser = ParserFactory.create(xml); return new BridgeXmlBlockParser(parser, mContext, mPlatformResourceFlag[0]); } @@ -317,10 +320,10 @@ public final class BridgeResources extends Resources { @Override public float getDimension(int id) throws NotFoundException { - ResourceValue value = getResourceValue(id, mPlatformResourceFlag); + Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag); if (value != null) { - String v = value.getValue(); + String v = value.getSecond().getValue(); if (v != null) { if (v.equals(BridgeConstants.MATCH_PARENT) || @@ -330,7 +333,8 @@ public final class BridgeResources extends Resources { return LayoutParams.WRAP_CONTENT; } - if (ResourceHelper.stringToFloat(v, mTmpValue) && + if (ResourceHelper.parseFloatAttribute( + value.getFirst(), v, mTmpValue, true /*requireUnit*/) && mTmpValue.type == TypedValue.TYPE_DIMENSION) { return mTmpValue.getDimension(mMetrics); } @@ -346,13 +350,14 @@ public final class BridgeResources extends Resources { @Override public int getDimensionPixelOffset(int id) throws NotFoundException { - ResourceValue value = getResourceValue(id, mPlatformResourceFlag); + Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag); if (value != null) { - String v = value.getValue(); + String v = value.getSecond().getValue(); if (v != null) { - if (ResourceHelper.stringToFloat(v, mTmpValue) && + if (ResourceHelper.parseFloatAttribute( + value.getFirst(), v, mTmpValue, true /*requireUnit*/) && mTmpValue.type == TypedValue.TYPE_DIMENSION) { return TypedValue.complexToDimensionPixelOffset(mTmpValue.data, mMetrics); } @@ -368,13 +373,14 @@ public final class BridgeResources extends Resources { @Override public int getDimensionPixelSize(int id) throws NotFoundException { - ResourceValue value = getResourceValue(id, mPlatformResourceFlag); + Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag); if (value != null) { - String v = value.getValue(); + String v = value.getSecond().getValue(); if (v != null) { - if (ResourceHelper.stringToFloat(v, mTmpValue) && + if (ResourceHelper.parseFloatAttribute( + value.getFirst(), v, mTmpValue, true /*requireUnit*/) && mTmpValue.type == TypedValue.TYPE_DIMENSION) { return TypedValue.complexToDimensionPixelSize(mTmpValue.data, mMetrics); } @@ -390,10 +396,10 @@ public final class BridgeResources extends Resources { @Override public int getInteger(int id) throws NotFoundException { - ResourceValue value = getResourceValue(id, mPlatformResourceFlag); + Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag); - if (value != null && value.getValue() != null) { - String v = value.getValue(); + if (value != null && value.getSecond().getValue() != null) { + String v = value.getSecond().getValue(); int radix = 10; if (v.startsWith("0x")) { v = v.substring(2); @@ -445,10 +451,10 @@ public final class BridgeResources extends Resources { @Override public String getString(int id) throws NotFoundException { - ResourceValue value = getResourceValue(id, mPlatformResourceFlag); + Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag); - if (value != null && value.getValue() != null) { - return value.getValue(); + if (value != null && value.getSecond().getValue() != null) { + return value.getSecond().getValue(); } // id was not found or not resolved. Throw a NotFoundException. @@ -461,13 +467,14 @@ public final class BridgeResources extends Resources { @Override public void getValue(int id, TypedValue outValue, boolean resolveRefs) throws NotFoundException { - ResourceValue value = getResourceValue(id, mPlatformResourceFlag); + Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag); if (value != null) { - String v = value.getValue(); + String v = value.getSecond().getValue(); if (v != null) { - if (ResourceHelper.stringToFloat(v, outValue)) { + if (ResourceHelper.parseFloatAttribute(value.getFirst(), v, outValue, + false /*requireUnit*/)) { return; } @@ -490,19 +497,17 @@ public final class BridgeResources extends Resources { @Override public XmlResourceParser getXml(int id) throws NotFoundException { - ResourceValue value = getResourceValue(id, mPlatformResourceFlag); + Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag); if (value != null) { - String v = value.getValue(); + String v = value.getSecond().getValue(); if (v != null) { // check this is a file - File f = new File(value.getValue()); + File f = new File(v); if (f.isFile()) { try { - KXmlParser parser = new KXmlParser(); - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); - parser.setInput(new FileInputStream(f), "UTF-8"); //$NON-NLS-1$); + XmlPullParser parser = ParserFactory.create(f); return new BridgeXmlBlockParser(parser, mContext, mPlatformResourceFlag[0]); } catch (XmlPullParserException e) { @@ -535,9 +540,7 @@ public final class BridgeResources extends Resources { File f = new File(file); try { - KXmlParser parser = new KXmlParser(); - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); - parser.setInput(new FileInputStream(f), "UTF-8"); //$NON-NLS-1$); + XmlPullParser parser = ParserFactory.create(f); return new BridgeXmlBlockParser(parser, mContext, mPlatformResourceFlag[0]); } catch (XmlPullParserException e) { @@ -554,10 +557,10 @@ public final class BridgeResources extends Resources { @Override public InputStream openRawResource(int id) throws NotFoundException { - ResourceValue value = getResourceValue(id, mPlatformResourceFlag); + Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag); if (value != null) { - String path = value.getValue(); + String path = value.getSecond().getValue(); if (path != null) { // check this is a file diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java index b1fbf08..260cdc8 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java @@ -24,10 +24,10 @@ import com.android.ide.common.rendering.api.StyleResourceValue; import com.android.internal.util.XmlUtils; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.BridgeConstants; +import com.android.layoutlib.bridge.impl.ParserFactory; import com.android.layoutlib.bridge.impl.ResourceHelper; import com.android.resources.ResourceType; -import org.kxml2.io.KXmlParser; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -41,7 +41,6 @@ import android.view.LayoutInflater_Delegate; import android.view.ViewGroup.LayoutParams; import java.io.File; -import java.io.FileInputStream; import java.util.Arrays; import java.util.Map; @@ -211,7 +210,7 @@ public final class BridgeTypedArray extends TypedArray { Map<String, Integer> map = null; if (mPlatformStyleable) { map = Bridge.getEnumValues(mNames[index]); - } else { + } else if (mStyleableName != null) { // get the styleable matching the resolved name RenderResources res = mContext.getRenderResources(); ResourceValue styleable = res.getProjectResource(ResourceType.DECLARE_STYLEABLE, @@ -331,9 +330,7 @@ public final class BridgeTypedArray extends TypedArray { File f = new File(value); if (f.isFile()) { try { - KXmlParser parser = new KXmlParser(); - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); - parser.setInput(new FileInputStream(f), "UTF-8"); //$NON-NLS-1$); + XmlPullParser parser = ParserFactory.create(f); BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser( parser, mContext, resValue.isFramework()); @@ -377,26 +374,7 @@ public final class BridgeTypedArray extends TypedArray { */ @Override public int getInteger(int index, int defValue) { - if (mResourceData[index] == null) { - return defValue; - } - - String s = mResourceData[index].getValue(); - - if (s != null) { - try { - return Integer.parseInt(s); - } catch (NumberFormatException e) { - Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT, - String.format( - "\"%s\" in attribute \"%2$s\" cannont be converted to an integer.", - s, mNames[index]), null /*data*/); - - // The default value is returned below. - } - } - - return defValue; + return getInt(index, defValue); } /** @@ -434,7 +412,7 @@ public final class BridgeTypedArray extends TypedArray { return defValue; } - if (ResourceHelper.stringToFloat(s, mValue)) { + if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true /*requireUnit*/)) { return mValue.getDimension(mBridgeResources.mMetrics); } @@ -561,7 +539,7 @@ public final class BridgeTypedArray extends TypedArray { throw new RuntimeException(); } - if (ResourceHelper.stringToFloat(s, mValue)) { + if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true /*requireUnit*/)) { float f = mValue.getDimension(mBridgeResources.mMetrics); final int res = (int)(f+0.5f); @@ -599,14 +577,15 @@ public final class BridgeTypedArray extends TypedArray { return defValue; } - if (ResourceHelper.stringToFloat(value, mValue)) { + if (ResourceHelper.parseFloatAttribute(mNames[index], value, mValue, + false /*requireUnit*/)) { return mValue.getFraction(base, pbase); } // looks like we were unable to resolve the fraction value Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT, String.format( - "\"%1$s\" in attribute \"%2$s\" cannont be converted to a fraction.", + "\"%1$s\" in attribute \"%2$s\" cannot be converted to a fraction.", value, mNames[index]), null /*data*/); return defValue; @@ -803,7 +782,8 @@ public final class BridgeTypedArray extends TypedArray { String s = mResourceData[index].getValue(); - return ResourceHelper.stringToFloat(s, outValue); + return ResourceHelper.parseFloatAttribute(mNames[index], s, outValue, + false /*requireUnit*/); } /** diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java index 70dbaa4..1016b32 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java @@ -18,6 +18,7 @@ package com.android.layoutlib.bridge.android; import com.android.ide.common.rendering.api.ILayoutPullParser; +import com.android.layoutlib.bridge.impl.ParserFactory; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -54,6 +55,10 @@ public class BridgeXmlBlockParser implements XmlResourceParser { * @param platformFile Indicates whether the the file is a platform file or not. */ public BridgeXmlBlockParser(XmlPullParser parser, BridgeContext context, boolean platformFile) { + if (ParserFactory.LOG_PARSER) { + System.out.println("CRTE " + parser.toString()); + } + mParser = parser; mContext = context; mPlatformFile = platformFile; @@ -65,6 +70,10 @@ public class BridgeXmlBlockParser implements XmlResourceParser { } } + public XmlPullParser getParser() { + return mParser; + } + public boolean isPlatformFile() { return mPlatformFile; } @@ -247,18 +256,63 @@ public class BridgeXmlBlockParser implements XmlResourceParser { public int next() throws XmlPullParserException, IOException { if (!mStarted) { mStarted = true; + + if (ParserFactory.LOG_PARSER) { + System.out.println("STRT " + mParser.toString()); + } + return START_DOCUMENT; } + int ev = mParser.next(); + if (ParserFactory.LOG_PARSER) { + System.out.println("NEXT " + mParser.toString() + " " + + eventTypeToString(mEventType) + " -> " + eventTypeToString(ev)); + } + if (ev == END_TAG && mParser.getDepth() == 1) { // done with parser remove it from the context stack. ensurePopped(); + + if (ParserFactory.LOG_PARSER) { + System.out.println(""); + } } + mEventType = ev; return ev; } + public static String eventTypeToString(int eventType) { + switch (eventType) { + case START_DOCUMENT: + return "START_DOC"; + case END_DOCUMENT: + return "END_DOC"; + case START_TAG: + return "START_TAG"; + case END_TAG: + return "END_TAG"; + case TEXT: + return "TEXT"; + case CDSECT: + return "CDSECT"; + case ENTITY_REF: + return "ENTITY_REF"; + case IGNORABLE_WHITESPACE: + return "IGNORABLE_WHITESPACE"; + case PROCESSING_INSTRUCTION: + return "PROCESSING_INSTRUCTION"; + case COMMENT: + return "COMMENT"; + case DOCDECL: + return "DOCDECL"; + } + + return "????"; + } + public void require(int type, String namespace, String name) throws XmlPullParserException { if (type != getEventType() diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java index 060e6ee..df701d5 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java @@ -22,11 +22,11 @@ import com.android.ide.common.rendering.api.StyleResourceValue; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.android.BridgeContext; import com.android.layoutlib.bridge.android.BridgeXmlBlockParser; +import com.android.layoutlib.bridge.impl.ParserFactory; import com.android.layoutlib.bridge.impl.ResourceHelper; import com.android.resources.Density; import com.android.resources.ResourceType; -import org.kxml2.io.KXmlParser; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -60,7 +60,7 @@ abstract class CustomBar extends LinearLayout { protected abstract TextView getStyleableTextView(); - protected CustomBar(Context context, Density density, String layoutPath) + protected CustomBar(Context context, Density density, String layoutPath, String name) throws XmlPullParserException { super(context); setOrientation(LinearLayout.HORIZONTAL); @@ -69,11 +69,8 @@ abstract class CustomBar extends LinearLayout { LayoutInflater inflater = (LayoutInflater) getContext().getSystemService( Context.LAYOUT_INFLATER_SERVICE); - KXmlParser parser = new KXmlParser(); - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); - parser.setInput( - getClass().getResourceAsStream(layoutPath), - "UTF8"); //$NON-NLS-1$ + XmlPullParser parser = ParserFactory.create(getClass().getResourceAsStream(layoutPath), + name); BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser( parser, (BridgeContext) context, false /*platformFile*/); @@ -230,7 +227,8 @@ abstract class CustomBar extends LinearLayout { if (textSize != null) { TypedValue out = new TypedValue(); - if (ResourceHelper.stringToFloat(textSize.getValue(), out)) { + if (ResourceHelper.parseFloatAttribute("textSize", textSize.getValue(), out, + true /*requireUnit*/)) { textView.setTextSize( out.getDimension(bridgeContext.getResources().mMetrics)); } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FakeActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FakeActionBar.java index 3af4e3a..f6edea4 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FakeActionBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FakeActionBar.java @@ -29,7 +29,7 @@ public class FakeActionBar extends CustomBar { public FakeActionBar(Context context, Density density, String label, String icon) throws XmlPullParserException { - super(context, density, "/bars/action_bar.xml"); + super(context, density, "/bars/action_bar.xml", "action_bar.xml"); // Cannot access the inside items through id because no R.id values have been // created for them. diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java index 9fab51a..5569e06 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java @@ -30,7 +30,7 @@ import android.widget.TextView; public class PhoneSystemBar extends CustomBar { public PhoneSystemBar(Context context, Density density) throws XmlPullParserException { - super(context, density, "/bars/phone_system_bar.xml"); + super(context, density, "/bars/phone_system_bar.xml", "phone_system_bar.xml"); setGravity(mGravity | Gravity.RIGHT); setBackgroundColor(0xFF000000); diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TabletSystemBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TabletSystemBar.java index 5ca68fa..456ddb4 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TabletSystemBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TabletSystemBar.java @@ -29,7 +29,7 @@ import android.widget.TextView; public class TabletSystemBar extends CustomBar { public TabletSystemBar(Context context, Density density) throws XmlPullParserException { - super(context, density, "/bars/tablet_system_bar.xml"); + super(context, density, "/bars/tablet_system_bar.xml", "tablet_system_bar.xml"); setBackgroundColor(0xFF000000); diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java index d7401d9..5f5ebc4 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java @@ -29,7 +29,7 @@ public class TitleBar extends CustomBar { public TitleBar(Context context, Density density, String label) throws XmlPullParserException { - super(context, density, "/bars/title_bar.xml"); + super(context, density, "/bars/title_bar.xml", "title_bar.xml"); // Cannot access the inside items through id because no R.id values have been // created for them. diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java new file mode 100644 index 0000000..a235ec3 --- /dev/null +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2011 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.layoutlib.bridge.impl; + + +import org.kxml2.io.KXmlParser; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; + +/** + * A factory for {@link XmlPullParser}. + * + */ +public class ParserFactory { + + private final static String ENCODING = "UTF-8"; //$NON-NLS-1$ + + public final static boolean LOG_PARSER = false; + + public static XmlPullParser create(File f) + throws XmlPullParserException, FileNotFoundException { + KXmlParser parser = instantiateParser(f.getName()); + parser.setInput(new FileInputStream(f), ENCODING); + return parser; + } + + public static XmlPullParser create(InputStream stream, String name) + throws XmlPullParserException { + KXmlParser parser = instantiateParser(name); + parser.setInput(stream, ENCODING); + return parser; + } + + private static KXmlParser instantiateParser(String name) throws XmlPullParserException { + KXmlParser parser; + if (name != null) { + parser = new CustomParser(name); + } else { + parser = new KXmlParser(); + } + parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); + return parser; + } + + private static class CustomParser extends KXmlParser { + private final String mName; + + CustomParser(String name) { + super(); + mName = name; + } + + @Override + public String toString() { + return mName; + } + } +} diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java index b800519..aa30e29 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java @@ -984,7 +984,8 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { "status_bar_height"); if (value != null) { - TypedValue typedValue = ResourceHelper.getValue(value.getValue()); + TypedValue typedValue = ResourceHelper.getValue("status_bar_height", + value.getValue(), true /*requireUnit*/); if (typedValue != null) { // compute the pixel value based on the display metrics mStatusBarSize = (int)typedValue.getDimension(metrics); @@ -1016,7 +1017,8 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { if (value != null) { // get the numerical value, if available - TypedValue typedValue = ResourceHelper.getValue(value.getValue()); + TypedValue typedValue = ResourceHelper.getValue("actionBarSize", value.getValue(), + true /*requireUnit*/); if (typedValue != null) { // compute the pixel value based on the display metrics mActionBarSize = (int)typedValue.getDimension(metrics); @@ -1040,7 +1042,8 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { if (value != null) { // get the numerical value, if available - TypedValue typedValue = ResourceHelper.getValue(value.getValue()); + TypedValue typedValue = ResourceHelper.getValue("windowTitleSize", + value.getValue(), true /*requireUnit*/); if (typedValue != null) { // compute the pixel value based on the display metrics mTitleBarSize = (int)typedValue.getDimension(metrics); @@ -1062,7 +1065,8 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { "status_bar_height"); if (value != null) { - TypedValue typedValue = ResourceHelper.getValue(value.getValue()); + TypedValue typedValue = ResourceHelper.getValue("status_bar_height", + value.getValue(), true /*requireUnit*/); if (typedValue != null) { // compute the pixel value based on the display metrics mSystemBarSize = (int)typedValue.getDimension(metrics); diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java index e5efa4e..6dcb693 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java @@ -27,7 +27,6 @@ import com.android.ninepatch.NinePatch; import com.android.ninepatch.NinePatchChunk; import com.android.resources.Density; -import org.kxml2.io.KXmlParser; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -121,9 +120,7 @@ public final class ResourceHelper { try { // let the framework inflate the ColorStateList from the XML file, by // providing an XmlPullParser - KXmlParser parser = new KXmlParser(); - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); - parser.setInput(new FileInputStream(f), "UTF-8"); //$NON-NLS-1$); + XmlPullParser parser = ParserFactory.create(f); BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser( parser, context, resValue.isFramework()); @@ -203,9 +200,7 @@ public final class ResourceHelper { if (f.isFile()) { try { // let the framework inflate the Drawable from the XML file. - KXmlParser parser = new KXmlParser(); - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); - parser.setInput(new FileInputStream(f), "UTF-8"); //$NON-NLS-1$); + XmlPullParser parser = ParserFactory.create(f); BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser( parser, context, value.isFramework()); @@ -341,11 +336,11 @@ public final class ResourceHelper { }; /** - * Returns the raw value from the given string. + * Returns the raw value from the given attribute float-type value string. * This object is only valid until the next call on to {@link ResourceHelper}. */ - public static TypedValue getValue(String s) { - if (stringToFloat(s, mValue)) { + public static TypedValue getValue(String attribute, String value, boolean requireUnit) { + if (parseFloatAttribute(attribute, value, mValue, requireUnit)) { return mValue; } @@ -353,22 +348,27 @@ public final class ResourceHelper { } /** - * Convert the string into a {@link TypedValue}. - * @param s - * @param outValue + * Parse a float attribute and return the parsed value into a given TypedValue. + * @param attribute the name of the attribute. Can be null if <var>requireUnit</var> is false. + * @param value the string value of the attribute + * @param outValue the TypedValue to receive the parsed value + * @param requireUnit whether the value is expected to contain a unit. * @return true if success. */ - public static boolean stringToFloat(String s, TypedValue outValue) { + public static boolean parseFloatAttribute(String attribute, String value, + TypedValue outValue, boolean requireUnit) { + assert requireUnit == false || attribute != null; + // remove the space before and after - s = s.trim(); - int len = s.length(); + value = value.trim(); + int len = value.length(); if (len <= 0) { return false; } // check that there's no non ascii characters. - char[] buf = s.toCharArray(); + char[] buf = value.toCharArray(); for (int i = 0 ; i < len ; i++) { if (buf[i] > 255) { return false; @@ -381,7 +381,7 @@ public final class ResourceHelper { } // now look for the string that is after the float... - Matcher m = sFloatPattern.matcher(s); + Matcher m = sFloatPattern.matcher(value); if (m.matches()) { String f_str = m.group(1); String end = m.group(2); @@ -397,45 +397,7 @@ public final class ResourceHelper { if (end.length() > 0 && end.charAt(0) != ' ') { // Might be a unit... if (parseUnit(end, outValue, sFloatOut)) { - - f *= sFloatOut[0]; - boolean neg = f < 0; - if (neg) { - f = -f; - } - long bits = (long)(f*(1<<23)+.5f); - int radix; - int shift; - if ((bits&0x7fffff) == 0) { - // Always use 23p0 if there is no fraction, just to make - // things easier to read. - radix = TypedValue.COMPLEX_RADIX_23p0; - shift = 23; - } else if ((bits&0xffffffffff800000L) == 0) { - // Magnitude is zero -- can fit in 0 bits of precision. - radix = TypedValue.COMPLEX_RADIX_0p23; - shift = 0; - } else if ((bits&0xffffffff80000000L) == 0) { - // Magnitude can fit in 8 bits of precision. - radix = TypedValue.COMPLEX_RADIX_8p15; - shift = 8; - } else if ((bits&0xffffff8000000000L) == 0) { - // Magnitude can fit in 16 bits of precision. - radix = TypedValue.COMPLEX_RADIX_16p7; - shift = 16; - } else { - // Magnitude needs entire range, so no fractional part. - radix = TypedValue.COMPLEX_RADIX_23p0; - shift = 23; - } - int mantissa = (int)( - (bits>>shift) & TypedValue.COMPLEX_MANTISSA_MASK); - if (neg) { - mantissa = (-mantissa) & TypedValue.COMPLEX_MANTISSA_MASK; - } - outValue.data |= - (radix<<TypedValue.COMPLEX_RADIX_SHIFT) - | (mantissa<<TypedValue.COMPLEX_MANTISSA_SHIFT); + computeTypedValue(outValue, f, sFloatOut[0]); return true; } return false; @@ -446,8 +408,20 @@ public final class ResourceHelper { if (end.length() == 0) { if (outValue != null) { - outValue.type = TypedValue.TYPE_FLOAT; - outValue.data = Float.floatToIntBits(f); + if (requireUnit == false) { + outValue.type = TypedValue.TYPE_FLOAT; + outValue.data = Float.floatToIntBits(f); + } else { + // no unit when required? Use dp and out an error. + applyUnit(sUnitNames[1], outValue, sFloatOut); + computeTypedValue(outValue, f, sFloatOut[0]); + + Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE, + String.format( + "Dimension \"%1$s\" in attribute \"%2$s\" is missing unit!", + value, attribute), + null); + } return true; } } @@ -456,20 +430,64 @@ public final class ResourceHelper { return false; } + private static void computeTypedValue(TypedValue outValue, float value, float scale) { + value *= scale; + boolean neg = value < 0; + if (neg) { + value = -value; + } + long bits = (long)(value*(1<<23)+.5f); + int radix; + int shift; + if ((bits&0x7fffff) == 0) { + // Always use 23p0 if there is no fraction, just to make + // things easier to read. + radix = TypedValue.COMPLEX_RADIX_23p0; + shift = 23; + } else if ((bits&0xffffffffff800000L) == 0) { + // Magnitude is zero -- can fit in 0 bits of precision. + radix = TypedValue.COMPLEX_RADIX_0p23; + shift = 0; + } else if ((bits&0xffffffff80000000L) == 0) { + // Magnitude can fit in 8 bits of precision. + radix = TypedValue.COMPLEX_RADIX_8p15; + shift = 8; + } else if ((bits&0xffffff8000000000L) == 0) { + // Magnitude can fit in 16 bits of precision. + radix = TypedValue.COMPLEX_RADIX_16p7; + shift = 16; + } else { + // Magnitude needs entire range, so no fractional part. + radix = TypedValue.COMPLEX_RADIX_23p0; + shift = 23; + } + int mantissa = (int)( + (bits>>shift) & TypedValue.COMPLEX_MANTISSA_MASK); + if (neg) { + mantissa = (-mantissa) & TypedValue.COMPLEX_MANTISSA_MASK; + } + outValue.data |= + (radix<<TypedValue.COMPLEX_RADIX_SHIFT) + | (mantissa<<TypedValue.COMPLEX_MANTISSA_SHIFT); + } + private static boolean parseUnit(String str, TypedValue outValue, float[] outScale) { str = str.trim(); for (UnitEntry unit : sUnitNames) { if (unit.name.equals(str)) { - outValue.type = unit.type; - outValue.data = unit.unit << TypedValue.COMPLEX_UNIT_SHIFT; - outScale[0] = unit.scale; - + applyUnit(unit, outValue, outScale); return true; } } return false; } + + private static void applyUnit(UnitEntry unit, TypedValue outValue, float[] outScale) { + outValue.type = unit.type; + outValue.data = unit.unit << TypedValue.COMPLEX_UNIT_SHIFT; + outScale[0] = unit.scale; + } } diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java index 70d5446..96436fe 100644 --- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java +++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java @@ -16,14 +16,11 @@ package com.android.layoutlib.bridge.android; -import com.android.layoutlib.bridge.android.BridgeXmlBlockParser; +import com.android.layoutlib.bridge.impl.ParserFactory; -import org.kxml2.io.KXmlParser; import org.w3c.dom.Node; import org.xmlpull.v1.XmlPullParser; -import java.io.InputStream; - import junit.framework.TestCase; public class BridgeXmlBlockParserTest extends TestCase { @@ -39,12 +36,12 @@ public class BridgeXmlBlockParserTest extends TestCase { } public void testXmlBlockParser() throws Exception { - XmlPullParser parser = new KXmlParser(); - parser = new BridgeXmlBlockParser(parser, null, false /* platformResourceFlag */); - InputStream input = this.getClass().getClassLoader().getResourceAsStream( - "com/android/layoutlib/testdata/layout1.xml"); - parser.setInput(input, "UTF-8"); //$NON-NLS-1$ + XmlPullParser parser = ParserFactory.create( + getClass().getResourceAsStream("com/android/layoutlib/testdata/layout1.xml"), + "layout1.xml"); + + parser = new BridgeXmlBlockParser(parser, null, false /* platformResourceFlag */); assertEquals(XmlPullParser.START_DOCUMENT, parser.next()); diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java index 3df3736..2a033d1 100644 --- a/wifi/java/android/net/wifi/WifiStateMachine.java +++ b/wifi/java/android/net/wifi/WifiStateMachine.java @@ -1028,9 +1028,6 @@ public class WifiStateMachine extends StateMachine { boolean wifiTethered = false; boolean wifiAvailable = false; - IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); - INetworkManagementService service = INetworkManagementService.Stub.asInterface(b); - if (mCm == null) { mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); } @@ -1043,14 +1040,14 @@ public class WifiStateMachine extends StateMachine { InterfaceConfiguration ifcg = null; try { - ifcg = service.getInterfaceConfig(intf); + ifcg = nwService.getInterfaceConfig(intf); if (ifcg != null) { /* IP/netmask: 192.168.43.1/255.255.255.0 */ ifcg.addr = new LinkAddress(NetworkUtils.numericToInetAddress( "192.168.43.1"), 24); ifcg.interfaceFlags = "[up]"; - service.setInterfaceConfig(intf, ifcg); + nwService.setInterfaceConfig(intf, ifcg); } } catch (Exception e) { Log.e(TAG, "Error configuring interface " + intf + ", :" + e); @@ -1374,7 +1371,7 @@ public class WifiStateMachine extends StateMachine { intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | Intent.FLAG_RECEIVER_REPLACE_PENDING); intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, mNetworkInfo); - intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, mLinkProperties); + intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, new LinkProperties (mLinkProperties)); if (bssid != null) intent.putExtra(WifiManager.EXTRA_BSSID, bssid); mContext.sendStickyBroadcast(intent); @@ -1390,7 +1387,7 @@ public class WifiStateMachine extends StateMachine { private void sendLinkConfigurationChangedBroadcast() { Intent intent = new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); - intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, mLinkProperties); + intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, new LinkProperties(mLinkProperties)); mContext.sendBroadcast(intent); } @@ -1438,7 +1435,6 @@ public class WifiStateMachine extends StateMachine { /* BSSID is valid only in ASSOCIATING state */ mWifiInfo.setBSSID(stateChangeResult.BSSID); } - setNetworkDetailedState(WifiInfo.getDetailedStateOf(state)); mSupplicantStateTracker.sendMessage(Message.obtain(message)); mWpsStateMachine.sendMessage(Message.obtain(message)); @@ -1451,19 +1447,23 @@ public class WifiStateMachine extends StateMachine { * using the interface, stopping DHCP & disabling interface */ private void handleNetworkDisconnect() { - Log.d(TAG, "Reset connections and stopping DHCP"); + Log.d(TAG, "Stopping DHCP and clearing IP"); /* - * Reset connections & stop DHCP + * stop DHCP */ - NetworkUtils.resetConnections(mInterfaceName); - if (mDhcpStateMachine != null) { mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP); mDhcpStateMachine.quit(); mDhcpStateMachine = null; } + try { + nwService.clearInterfaceAddresses(mInterfaceName); + } catch (Exception e) { + Log.e(TAG, "Failed to clear IP addresses on disconnect" + e); + } + /* Reset data structures */ mWifiInfo.setInetAddress(null); mWifiInfo.setBSSID(null); @@ -1547,7 +1547,6 @@ public class WifiStateMachine extends StateMachine { if (!linkProperties.equals(mLinkProperties)) { Log.d(TAG, "Link configuration changed for netId: " + mLastNetworkId + " old: " + mLinkProperties + "new: " + linkProperties); - NetworkUtils.resetConnections(mInterfaceName); mLinkProperties = linkProperties; sendLinkConfigurationChangedBroadcast(); } @@ -2660,13 +2659,11 @@ public class WifiStateMachine extends StateMachine { } else { DhcpInfoInternal dhcpInfoInternal = WifiConfigStore.getIpConfiguration( mLastNetworkId); - IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); - INetworkManagementService netd = INetworkManagementService.Stub.asInterface(b); InterfaceConfiguration ifcg = new InterfaceConfiguration(); ifcg.addr = dhcpInfoInternal.makeLinkAddress(); ifcg.interfaceFlags = "[up]"; try { - netd.setInterfaceConfig(mInterfaceName, ifcg); + nwService.setInterfaceConfig(mInterfaceName, ifcg); Log.v(TAG, "Static IP configuration succeeded"); sendMessage(CMD_STATIC_IP_SUCCESS, dhcpInfoInternal); } catch (RemoteException re) { @@ -2820,7 +2817,6 @@ public class WifiStateMachine extends StateMachine { if (mWifiInfo.getNetworkId() == result.getNetworkId()) { if (result.hasIpChanged()) { Log.d(TAG,"Reconfiguring IP on connection"); - NetworkUtils.resetConnections(mInterfaceName); transitionTo(mConnectingState); } if (result.hasProxyChanged()) { @@ -2979,7 +2975,12 @@ public class WifiStateMachine extends StateMachine { /* Ignore network disconnect */ case NETWORK_DISCONNECTION_EVENT: break; - case CMD_START_SCAN: + case SUPPLICANT_STATE_CHANGE_EVENT: + StateChangeResult stateChangeResult = (StateChangeResult) message.obj; + setNetworkDetailedState(WifiInfo.getDetailedStateOf(stateChangeResult.state)); + /* ConnectModeState does the rest of the handling */ + return NOT_HANDLED; + case CMD_START_SCAN: /* Disable background scan temporarily during a regular scan */ if (mEnableBackgroundScan) { WifiNative.enableBackgroundScanCommand(false); |