diff options
101 files changed, 2205 insertions, 663 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 a2fe825..12d9cc2 100644 --- a/api/current.txt +++ b/api/current.txt @@ -1632,6 +1632,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 +1659,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 +2450,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 +3239,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 +3522,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(); 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/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/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/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/provider/CalendarContract.java b/core/java/android/provider/CalendarContract.java index 3db1827..1a24716 100644 --- a/core/java/android/provider/CalendarContract.java +++ b/core/java/android/provider/CalendarContract.java @@ -648,7 +648,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 +1252,103 @@ public final class CalendarContract { } /** - * Fields and helpers for interacting with Events. + * Constants and helpers for the Events table, which contains details of a + * single event. <h3>Operations</h3> All operations can be done either as an + * app or as a sync adapter. To perform an operation as a sync adapter + * {@link #CALLER_IS_SYNCADAPTER} should be set to true in the Uri + * parameters and {@link #ACCOUNT_NAME} and {@link #ACCOUNT_TYPE} must be + * set. Sync adapters have write access to more columns but are restricted + * to a single account at a time. + * <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 on an Event the {@link Events#_ID} of the event + * must be provided either as an appended id to the Uri ( + * {@link ContentUris#withAppendedId}) or as the first selection item--the + * selection should start with "_id=?" and the first selectionArg should be + * the _id of the event. Updating an event must respect the same rules as + * inserting and is further restricted in the fields that can be written. + * See the section on Writing to Events.</dd> + * <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 +1460,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 { @@ -1771,7 +1882,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 +1993,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 +2172,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 +2266,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 +2306,8 @@ public final class CalendarContract { /** * Columns from the EventsRawTimes table + * + * @hide */ protected interface EventsRawTimesColumns { /** 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 index e767a85..74a930f 100644 --- a/core/java/android/util/LocaleUtil.java +++ b/core/java/android/util/LocaleUtil.java @@ -67,17 +67,8 @@ public class LocaleUtil { return TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE; } - final String localeWithSubtags = ICU.addLikelySubtags(locale.toString()); - if (localeWithSubtags == null) return getLayoutDirectionFromFirstChar(locale); - - // Need to check if we can extract the script subtag. For example, "Latn" in "en_Latn_US" - if (localeWithSubtags.length() <= 7 - || localeWithSubtags.charAt(2) != UNDERSCORE_CHAR - || localeWithSubtags.charAt(7) != UNDERSCORE_CHAR) { - return getLayoutDirectionFromFirstChar(locale); - } - // Extract the script subtag - final String scriptSubtag = localeWithSubtags.substring(3, 7); + 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)) { 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/widget/GridLayout.java b/core/java/android/widget/GridLayout.java index 544bc6b..e54c511 100644 --- a/core/java/android/widget/GridLayout.java +++ b/core/java/android/widget/GridLayout.java @@ -189,10 +189,7 @@ public class GridLayout extends ViewGroup { * {@inheritDoc} */ public GridLayout(Context context) { - super(context); - if (DEBUG) { - setWillNotDraw(false); - } + this(context, null, 0); } /** @@ -200,6 +197,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,8 +207,7 @@ 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) { @@ -2287,4 +2286,4 @@ public class GridLayout extends ViewGroup { return cellSize; } }; -}
\ No newline at end of file +} 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/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/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/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/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/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 e6dfc03..74d942f 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. --> diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index df22f15..0725c2f 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..be2997e 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -1767,4 +1767,7 @@ <public type="attr" name="verticalOffset" /> <public type="attr" name="horizontalOffset" /> + <public type="style" name="Widget.Holo.Button.Borderless.Small" /> + <public type="style" name="Widget.Holo.Light.Button.Borderless.Small" /> + </resources> diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml index 19b05c9..6e80326 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -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"> @@ -1864,6 +1872,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"> diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml index 5f77dc5..4a43e32 100644 --- a/core/res/res/values/themes.xml +++ b/core/res/res/values/themes.xml @@ -1411,6 +1411,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 +1421,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 +1434,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 +1461,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 +1500,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 +1510,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 +1523,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 +1549,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/util/LocaleUtilTest.java b/core/tests/coretests/src/android/util/LocaleUtilTest.java index 5aa99c1..203781f 100644 --- a/core/tests/coretests/src/android/util/LocaleUtilTest.java +++ b/core/tests/coretests/src/android/util/LocaleUtilTest.java @@ -18,14 +18,12 @@ package android.util; import java.util.Locale; -import android.content.res.Configuration; import android.test.AndroidTestCase; import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetNew; -import static android.util.LocaleUtil.TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE; import static android.util.LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE; -import static android.util.LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE; +import static android.util.LocaleUtil.TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE; public class LocaleUtilTest extends AndroidTestCase { 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/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/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/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/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/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/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 cf25818..2a033d1 100644 --- a/wifi/java/android/net/wifi/WifiStateMachine.java +++ b/wifi/java/android/net/wifi/WifiStateMachine.java @@ -1435,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)); @@ -2976,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); |