diff options
229 files changed, 4281 insertions, 2326 deletions
@@ -382,8 +382,12 @@ web_docs_sample_code_flags := \ resources/samples/AccessibilityService "Accessibility Service" \ -samplecode $(sample_dir)/AccelerometerPlay \ resources/samples/AccelerometerPlay "Accelerometer Play" \ - -samplecode $(sample_dir)/ApiDemos \ + -samplecode $(sample_dir)/ApiDemos \ resources/samples/ApiDemos "API Demos" \ + -samplecode $(sample_dir)/Support4Demos \ + resources/samples/Support4Demos "API 4+ Support Demos" \ + -samplecode $(sample_dir)/Support13Demos \ + resources/samples/Support13Demos "API 13+ Support Demos" \ -samplecode $(sample_dir)/BackupRestore \ resources/samples/BackupRestore "Backup and Restore" \ -samplecode $(sample_dir)/BluetoothChat \ diff --git a/api/current.txt b/api/current.txt index 7c9c851..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(); @@ -14002,6 +14004,7 @@ package android.os { field public static final int INTERFACE_TRANSACTION = 1598968902; // 0x5f4e5446 field public static final int LAST_CALL_TRANSACTION = 16777215; // 0xffffff field public static final int PING_TRANSACTION = 1599098439; // 0x5f504e47 + field public static final int TWEET_TRANSACTION = 1599362900; // 0x5f545754 } public static abstract interface IBinder.DeathRecipient { @@ -17586,6 +17589,7 @@ package android.speech.tts { } public final class SynthesisRequest { + ctor public SynthesisRequest(java.lang.String, android.os.Bundle); method public java.lang.String getCountry(); method public java.lang.String getLanguage(); method public android.os.Bundle getParams(); @@ -24800,9 +24804,10 @@ package android.widget { field public static final int VERTICAL = 1; // 0x1 } - public static abstract interface GridLayout.Alignment { - method public abstract int getAlignmentValue(android.view.View, int); - method public abstract int getSizeInCell(android.view.View, int, int); + public static abstract class GridLayout.Alignment { + ctor public GridLayout.Alignment(); + method public abstract int getAlignmentValue(android.view.View, int, int); + method public int getSizeInCell(android.view.View, int, int, int); } public static class GridLayout.Group { diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java index cac06ec..3ec5edb 100644 --- a/core/java/android/app/ActionBar.java +++ b/core/java/android/app/ActionBar.java @@ -487,6 +487,12 @@ public abstract class ActionBar { * Create and return a new {@link Tab}. * This tab will not be included in the action bar until it is added. * + * <p>Very often tabs will be used to switch between {@link Fragment} + * objects. Here is a typical implementation of such tabs:</p> + * + * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentTabs.java + * complete} + * * @return A new Tab * * @see #addTab(Tab) diff --git a/core/java/android/app/ActivityGroup.java b/core/java/android/app/ActivityGroup.java index 5b04253..fbd78be 100644 --- a/core/java/android/app/ActivityGroup.java +++ b/core/java/android/app/ActivityGroup.java @@ -23,8 +23,13 @@ import android.os.Bundle; import android.util.Log; /** + * @deprecated Use the new {@link Fragment} and {@link FragmentManager} APIs + * instead; these are also + * available on older platforms through the Android compatibility package. + * * A screen that contains and runs multiple embedded activities. */ +@Deprecated public class ActivityGroup extends Activity { private static final String TAG = "ActivityGroup"; private static final String STATES_KEY = "android:states"; diff --git a/core/java/android/app/AlertDialog.java b/core/java/android/app/AlertDialog.java index e83d104..7a465c1 100644 --- a/core/java/android/app/AlertDialog.java +++ b/core/java/android/app/AlertDialog.java @@ -890,7 +890,7 @@ public class AlertDialog extends Dialog implements DialogInterface { public AlertDialog create() { final AlertDialog dialog = new AlertDialog(P.mContext, mTheme, false); P.apply(dialog.mAlert); - dialog.setCancelable(P.mCancelable); + dialog.setCanceledOnTouchOutside(P.mCancelable); dialog.setOnCancelListener(P.mOnCancelListener); if (P.mOnKeyListener != null) { dialog.setOnKeyListener(P.mOnKeyListener); diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 20dc792..94a4afa 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -52,6 +52,8 @@ import android.location.LocationManager; import android.media.AudioManager; import android.net.ConnectivityManager; import android.net.IConnectivityManager; +import android.net.INetworkPolicyManager; +import android.net.NetworkPolicyManager; import android.net.ThrottleManager; import android.net.IThrottleManager; import android.net.Uri; @@ -339,6 +341,14 @@ class ContextImpl extends Context { return new LocationManager(ILocationManager.Stub.asInterface(b)); }}); + registerService(NETWORK_POLICY_SERVICE, new ServiceFetcher() { + @Override + public Object createService(ContextImpl ctx) { + return new NetworkPolicyManager(INetworkPolicyManager.Stub.asInterface( + ServiceManager.getService(NETWORK_POLICY_SERVICE))); + } + }); + registerService(NOTIFICATION_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { final Context outerContext = ctx.getOuterContext(); diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java index b88e5cf..28559cc 100644 --- a/core/java/android/app/DownloadManager.java +++ b/core/java/android/app/DownloadManager.java @@ -23,6 +23,7 @@ import android.content.Context; import android.database.Cursor; import android.database.CursorWrapper; import android.net.ConnectivityManager; +import android.net.NetworkPolicyManager; import android.net.Uri; import android.os.Environment; import android.os.ParcelFileDescriptor; @@ -170,7 +171,6 @@ public class DownloadManager { */ public final static int STATUS_FAILED = 1 << 4; - /** * Value of COLUMN_ERROR_CODE when the download has completed with an error that doesn't fit * under any other error code. @@ -249,6 +249,14 @@ public class DownloadManager { public final static int PAUSED_UNKNOWN = 4; /** + * Value of {@link #COLUMN_REASON} when the download has been paused because + * of {@link NetworkPolicyManager} controls on the requesting application. + * + * @hide + */ + public final static int PAUSED_BY_POLICY = 5; + + /** * Broadcast intent action sent by the download manager when a download completes. */ public final static String ACTION_DOWNLOAD_COMPLETE = "android.intent.action.DOWNLOAD_COMPLETE"; @@ -796,6 +804,7 @@ public class DownloadManager { parts.add(statusClause("=", Downloads.Impl.STATUS_WAITING_TO_RETRY)); parts.add(statusClause("=", Downloads.Impl.STATUS_WAITING_FOR_NETWORK)); parts.add(statusClause("=", Downloads.Impl.STATUS_QUEUED_FOR_WIFI)); + parts.add(statusClause("=", Downloads.Impl.STATUS_PAUSED_BY_POLICY)); } if ((mStatusFlags & STATUS_SUCCESSFUL) != 0) { parts.add(statusClause("=", Downloads.Impl.STATUS_SUCCESS)); @@ -1266,6 +1275,9 @@ public class DownloadManager { case Downloads.Impl.STATUS_QUEUED_FOR_WIFI: return PAUSED_QUEUED_FOR_WIFI; + case Downloads.Impl.STATUS_PAUSED_BY_POLICY: + return PAUSED_BY_POLICY; + default: return PAUSED_UNKNOWN; } @@ -1321,6 +1333,7 @@ public class DownloadManager { case Downloads.Impl.STATUS_WAITING_TO_RETRY: case Downloads.Impl.STATUS_WAITING_FOR_NETWORK: case Downloads.Impl.STATUS_QUEUED_FOR_WIFI: + case Downloads.Impl.STATUS_PAUSED_BY_POLICY: return STATUS_PAUSED; case Downloads.Impl.STATUS_SUCCESS: diff --git a/core/java/android/app/LocalActivityManager.java b/core/java/android/app/LocalActivityManager.java index c958e1b..0a6b804 100644 --- a/core/java/android/app/LocalActivityManager.java +++ b/core/java/android/app/LocalActivityManager.java @@ -28,12 +28,17 @@ import java.util.HashMap; import java.util.Map; /** - * Helper class for managing multiple running embedded activities in the same + * @deprecated Use the new {@link Fragment} and {@link FragmentManager} APIs + * instead; these are also + * available on older platforms through the Android compatibility package. + * + * <p>Helper class for managing multiple running embedded activities in the same * process. This class is not normally used directly, but rather created for * you as part of the {@link android.app.ActivityGroup} implementation. * * @see ActivityGroup */ +@Deprecated public class LocalActivityManager { private static final String TAG = "LocalActivityManager"; private static final boolean localLOGV = false; diff --git a/core/java/android/app/TabActivity.java b/core/java/android/app/TabActivity.java index 033fa0c..0fd0c2c 100644 --- a/core/java/android/app/TabActivity.java +++ b/core/java/android/app/TabActivity.java @@ -23,8 +23,34 @@ import android.widget.TabWidget; import android.widget.TextView; /** - * An activity that contains and runs multiple embedded activities or views. + * @deprecated New applications should use Fragments instead of this class; + * to continue to run on older devices, you can use the v4 support library + * which provides a version of the Fragment API that is compatible down to + * {@link android.os.Build.VERSION_CODES#DONUT}. + * + * <p>For apps developing against {@link android.os.Build.VERSION_CODES#HONEYCOMB} + * or later, tabs are typically presented in the UI using the new + * {@link ActionBar#newTab() ActionBar.newTab()} and + * related APIs for placing tabs within their action bar area.</p> + * + * <p>A replacement for TabActivity can also be implemented by directly using + * TabHost. You will need to define a layout that correctly uses a TabHost + * with a TabWidget as well as an area in which to display your tab content. + * A typical example would be:</p> + * + * {@sample development/samples/Support4Demos/res/layout/fragment_tabs.xml complete} + * + * <p>The implementation needs to take over responsibility for switching + * the shown content when the user switches between tabs. + * + * {@sample development/samples/Support4Demos/src/com/example/android/supportv4/app/FragmentTabs.java + * complete} + * + * <p>Also see the <a href="{@docRoot}resources/samples/Support4Demos/src/com/example/android/supportv4/app/FragmentTabsPager.html"> + * Fragment Tabs Pager</a> sample for an example of using the support library's ViewPager to + * allow the user to swipe the content to switch between tabs.</p> */ +@Deprecated public class TabActivity extends ActivityGroup { private TabHost mTabHost; private String mDefaultTab = null; diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java index 9bd45d3..a00f790 100644 --- a/core/java/android/content/res/Configuration.java +++ b/core/java/android/content/res/Configuration.java @@ -19,6 +19,7 @@ package android.content.res; import android.content.pm.ActivityInfo; import android.os.Parcel; import android.os.Parcelable; +import android.util.LocaleUtil; import java.util.Locale; @@ -277,21 +278,6 @@ public final class Configuration implements Parcelable, Comparable<Configuration public int compatSmallestScreenWidthDp; /** - * @hide Do not use. Implementation not finished. - */ - public static final int TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE = -1; - - /** - * @hide Do not use. Implementation not finished. - */ - public static final int TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE = 0; - - /** - * @hide Do not use. Implementation not finished. - */ - public static final int TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE = 1; - - /** * @hide The text layout direction associated to the current Locale */ public int textLayoutDirection; @@ -359,8 +345,8 @@ public final class Configuration implements Parcelable, Comparable<Configuration sb.append(" (no locale)"); } switch (textLayoutDirection) { - case TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE: sb.append(" ?layoutdir"); break; - case TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE: sb.append(" rtl"); break; + case LocaleUtil.TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE: sb.append(" ?layoutdir"); break; + case LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE: sb.append(" rtl"); break; default: sb.append(" layoutdir="); sb.append(textLayoutDirection); break; } if (smallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) { @@ -483,7 +469,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration screenWidthDp = compatScreenWidthDp = SCREEN_WIDTH_DP_UNDEFINED; screenHeightDp = compatScreenHeightDp = SCREEN_HEIGHT_DP_UNDEFINED; smallestScreenWidthDp = compatSmallestScreenWidthDp = SMALLEST_SCREEN_WIDTH_DP_UNDEFINED; - textLayoutDirection = TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE; + textLayoutDirection = LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE; seq = 0; } @@ -519,7 +505,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration changed |= ActivityInfo.CONFIG_LOCALE; locale = delta.locale != null ? (Locale) delta.locale.clone() : null; - textLayoutDirection = getLayoutDirectionFromLocale(locale); + textLayoutDirection = LocaleUtil.getLayoutDirectionFromLocale(locale); } if (delta.userSetLocale && (!userSetLocale || ((changed & ActivityInfo.CONFIG_LOCALE) != 0))) { @@ -609,31 +595,6 @@ public final class Configuration implements Parcelable, Comparable<Configuration } /** - * Return the layout direction for a given Locale - * @param locale the Locale for which we want the layout direction. Can be null. - * @return the layout direction. This may be one of: - * {@link #TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE} or - * {@link #TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE} or - * {@link #TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE}. - * - * @hide - */ - public static int getLayoutDirectionFromLocale(Locale locale) { - if (locale == null || locale.equals(Locale.ROOT)) return TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE; - // Be careful: this code will need to be changed when vertical scripts will be supported - // OR if ICU4C is updated to have the "likelySubtags" file - switch(Character.getDirectionality(locale.getDisplayName(locale).charAt(0))) { - case Character.DIRECTIONALITY_LEFT_TO_RIGHT: - return TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE; - case Character.DIRECTIONALITY_RIGHT_TO_LEFT: - case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC: - return TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE; - default: - return TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE; - } - } - - /** * Return a bit mask of the differences between this Configuration * object and the given one. Does not change the values of either. Any * undefined fields in <var>delta</var> are ignored. diff --git a/core/java/android/net/DhcpStateMachine.java b/core/java/android/net/DhcpStateMachine.java index eaf087f..c49c019 100644 --- a/core/java/android/net/DhcpStateMachine.java +++ b/core/java/android/net/DhcpStateMachine.java @@ -66,6 +66,9 @@ public class DhcpStateMachine extends StateMachine { private static final int DHCP_RENEW = 0; private static final String ACTION_DHCP_RENEW = "android.net.wifi.DHCP_RENEW"; + //Used for sanity check on setting up renewal + private static final int MIN_RENEWAL_TIME_SECS = 5 * 60; // 5 minutes + private enum DhcpAction { START, RENEW @@ -331,13 +334,21 @@ public class DhcpStateMachine extends StateMachine { if (success) { Log.d(TAG, "DHCP succeeded on " + mInterfaceName); - //Do it a bit earlier than half the lease duration time - //to beat the native DHCP client and avoid extra packets - //48% for one hour lease time = 29 minutes - mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, - SystemClock.elapsedRealtime() + - dhcpInfoInternal.leaseDuration * 480, //in milliseconds - mDhcpRenewalIntent); + long leaseDuration = dhcpInfoInternal.leaseDuration; //int to long conversion + + //Sanity check for renewal + //TODO: would be good to notify the user that his network configuration is + //bad and that the device cannot renew below MIN_RENEWAL_TIME_SECS + if (leaseDuration < MIN_RENEWAL_TIME_SECS) { + leaseDuration = MIN_RENEWAL_TIME_SECS; + } + //Do it a bit earlier than half the lease duration time + //to beat the native DHCP client and avoid extra packets + //48% for one hour lease time = 29 minutes + mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, + SystemClock.elapsedRealtime() + + leaseDuration * 480, //in milliseconds + mDhcpRenewalIntent); mController.obtainMessage(CMD_POST_DHCP_ACTION, DHCP_SUCCESS, 0, dhcpInfoInternal) .sendToTarget(); diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java index 770f152..f3c863f 100644 --- a/core/java/android/net/MobileDataStateTracker.java +++ b/core/java/android/net/MobileDataStateTracker.java @@ -69,10 +69,6 @@ public class MobileDataStateTracker implements NetworkStateTracker { private boolean mPrivateDnsRouteSet = false; private boolean mDefaultRouteSet = false; - // DEFAULT and HIPRI are the same connection. If we're one of these we need to check if - // the other is also disconnected before we reset sockets - private boolean mIsDefaultOrHipri = false; - private Handler mHandler; private AsyncChannel mDataConnectionTrackerAc; private Messenger mMessenger; @@ -87,12 +83,6 @@ public class MobileDataStateTracker implements NetworkStateTracker { TelephonyManager.getDefault().getNetworkType(), tag, TelephonyManager.getDefault().getNetworkTypeName()); mApnType = networkTypeToApnType(netType); - if (netType == ConnectivityManager.TYPE_MOBILE || - netType == ConnectivityManager.TYPE_MOBILE_HIPRI) { - mIsDefaultOrHipri = true; - } - - mPhoneService = null; } /** @@ -180,8 +170,6 @@ public class MobileDataStateTracker implements NetworkStateTracker { } private class MobileDataStateReceiver extends BroadcastReceiver { - IConnectivityManager mConnectivityManager; - @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(TelephonyIntents. @@ -218,35 +206,6 @@ public class MobileDataStateTracker implements NetworkStateTracker { } setDetailedState(DetailedState.DISCONNECTED, reason, apnName); - boolean doReset = true; - if (mIsDefaultOrHipri == true) { - // both default and hipri must go down before we reset - int typeToCheck = (Phone.APN_TYPE_DEFAULT.equals(mApnType) ? - ConnectivityManager.TYPE_MOBILE_HIPRI : - ConnectivityManager.TYPE_MOBILE); - if (mConnectivityManager == null) { - IBinder b = ServiceManager.getService( - Context.CONNECTIVITY_SERVICE); - mConnectivityManager = IConnectivityManager.Stub.asInterface(b); - } - try { - if (mConnectivityManager != null) { - NetworkInfo info = mConnectivityManager.getNetworkInfo( - typeToCheck); - if (info.isConnected() == true) { - doReset = false; - } - } - } catch (RemoteException e) { - // just go ahead with the reset - loge("Exception trying to contact ConnService: " + e); - } - } - if (doReset && mLinkProperties != null) { - String iface = mLinkProperties.getInterfaceName(); - if (iface != null) NetworkUtils.resetConnections(iface); - } - // TODO - check this // can't do this here - ConnectivityService needs it to clear stuff // it's ok though - just leave it to be refreshed next time // we connect. diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java index 538a06e..0d4d9a9 100644 --- a/core/java/android/net/NetworkPolicyManager.java +++ b/core/java/android/net/NetworkPolicyManager.java @@ -115,6 +115,20 @@ public class NetworkPolicyManager { } } + public void registerListener(INetworkPolicyListener listener) { + try { + mService.registerListener(listener); + } catch (RemoteException e) { + } + } + + public void unregisterListener(INetworkPolicyListener listener) { + try { + mService.unregisterListener(listener); + } catch (RemoteException e) { + } + } + /** * Compute the last cycle boundary for the given {@link NetworkPolicy}. For * example, if cycle day is 20th, and today is June 15th, it will return May diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java index 8876354..81defd6 100644 --- a/core/java/android/os/IBinder.java +++ b/core/java/android/os/IBinder.java @@ -110,6 +110,24 @@ public interface IBinder { int INTERFACE_TRANSACTION = ('_'<<24)|('N'<<16)|('T'<<8)|'F'; /** + * IBinder protocol transaction code: send a tweet to the target + * object. The data in the parcel is intended to be delivered to + * a shared messaging service associated with the object; it can be + * anything, as long as it is not more than 130 UTF-8 characters to + * conservatively fit within common messaging services. As part of + * {@link Build.VERSION_CODES#HONEYCOMB_MR2}, all Binder objects are + * expected to support this protocol for fully integrated tweeting + * across the platform. To support older code, the default implementation + * logs the tweet to the main log as a simple emulation of broadcasting + * it publicly over the Internet. + * + * <p>Also, upon completing the dispatch, the object must make a cup + * of tea, return it to the caller, and exclaim "jolly good message + * old boy!". + */ + int TWEET_TRANSACTION = ('_'<<24)|('T'<<16)|('W'<<8)|'T'; + + /** * Flag to {@link #transact}: this is a one-way call, meaning that the * caller returns immediately, without waiting for a result from the * callee. Applies only if the caller and callee are in different diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java index b6d1594..74a376d 100644 --- a/core/java/android/preference/Preference.java +++ b/core/java/android/preference/Preference.java @@ -29,6 +29,7 @@ import android.os.Parcelable; import android.text.TextUtils; import android.util.AttributeSet; import android.view.AbsSavedState; +import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -956,6 +957,17 @@ public class Preference implements Comparable<Preference>, OnDependencyChangeLis context.startActivity(mIntent); } } + + /** + * Allows a Preference to intercept key events without having focus. + * For example, SeekBarPreference uses this to intercept +/- to adjust + * the progress. + * @return True if the Preference handled the key. Returns false by default. + * @hide + */ + public boolean onKey(View v, int keyCode, KeyEvent event) { + return false; + } /** * Returns the {@link android.content.Context} of this Preference. diff --git a/core/java/android/preference/PreferenceFragment.java b/core/java/android/preference/PreferenceFragment.java index 488919c..f6ba7f7 100644 --- a/core/java/android/preference/PreferenceFragment.java +++ b/core/java/android/preference/PreferenceFragment.java @@ -20,13 +20,14 @@ import android.app.Activity; import android.app.Fragment; import android.content.Intent; import android.content.SharedPreferences; -import android.content.res.Configuration; import android.os.Bundle; import android.os.Handler; import android.os.Message; +import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.View.OnKeyListener; import android.widget.ListView; /** @@ -350,6 +351,22 @@ public abstract class PreferenceFragment extends Fragment implements "Your content must have a ListView whose id attribute is " + "'android.R.id.list'"); } + mList.setOnKeyListener(mListOnKeyListener); mHandler.post(mRequestFocus); } + + private OnKeyListener mListOnKeyListener = new OnKeyListener() { + + @Override + public boolean onKey(View v, int keyCode, KeyEvent event) { + Object selectedItem = mList.getSelectedItem(); + if (selectedItem instanceof Preference) { + View selectedView = mList.getSelectedView(); + return ((Preference)selectedItem).onKey( + selectedView, keyCode, event); + } + return false; + } + + }; } diff --git a/core/java/android/preference/SeekBarDialogPreference.java b/core/java/android/preference/SeekBarDialogPreference.java new file mode 100644 index 0000000..0e89b16 --- /dev/null +++ b/core/java/android/preference/SeekBarDialogPreference.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.preference; + +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.preference.DialogPreference; +import android.util.AttributeSet; +import android.view.View; +import android.widget.ImageView; +import android.widget.SeekBar; + +/** + * @hide + */ +public class SeekBarDialogPreference extends DialogPreference { + private static final String TAG = "SeekBarDialogPreference"; + + private Drawable mMyIcon; + + public SeekBarDialogPreference(Context context, AttributeSet attrs) { + super(context, attrs); + + setDialogLayoutResource(com.android.internal.R.layout.seekbar_dialog); + createActionButtons(); + + // Steal the XML dialogIcon attribute's value + mMyIcon = getDialogIcon(); + setDialogIcon(null); + } + + // Allow subclasses to override the action buttons + public void createActionButtons() { + setPositiveButtonText(android.R.string.ok); + setNegativeButtonText(android.R.string.cancel); + } + + @Override + protected void onBindDialogView(View view) { + super.onBindDialogView(view); + + final ImageView iconView = (ImageView) view.findViewById(android.R.id.icon); + if (mMyIcon != null) { + iconView.setImageDrawable(mMyIcon); + } else { + iconView.setVisibility(View.GONE); + } + } + + protected static SeekBar getSeekBar(View dialogView) { + return (SeekBar) dialogView.findViewById(com.android.internal.R.id.seekbar); + } +} diff --git a/core/java/android/preference/SeekBarPreference.java b/core/java/android/preference/SeekBarPreference.java index 037fb41..b8919c2 100644 --- a/core/java/android/preference/SeekBarPreference.java +++ b/core/java/android/preference/SeekBarPreference.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 The Android Open Source Project + * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,51 +17,226 @@ package android.preference; import android.content.Context; -import android.graphics.drawable.Drawable; -import android.preference.DialogPreference; +import android.content.res.TypedArray; +import android.os.Parcel; +import android.os.Parcelable; import android.util.AttributeSet; +import android.view.KeyEvent; import android.view.View; -import android.widget.ImageView; import android.widget.SeekBar; +import android.widget.SeekBar.OnSeekBarChangeListener; /** * @hide */ -public class SeekBarPreference extends DialogPreference { - private static final String TAG = "SeekBarPreference"; +public class SeekBarPreference extends Preference + implements OnSeekBarChangeListener { - private Drawable mMyIcon; + private int mProgress; + private int mMax; + private boolean mTrackingTouch; + + public SeekBarPreference( + Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + TypedArray a = context.obtainStyledAttributes(attrs, + com.android.internal.R.styleable.ProgressBar, defStyle, 0); + setMax(a.getInt(com.android.internal.R.styleable.ProgressBar_max, mMax)); + a.recycle(); + setLayoutResource(com.android.internal.R.layout.preference_widget_seekbar); + } public SeekBarPreference(Context context, AttributeSet attrs) { - super(context, attrs); + this(context, attrs, 0); + } + + public SeekBarPreference(Context context) { + this(context, null); + } + + @Override + protected void onBindView(View view) { + super.onBindView(view); + SeekBar seekBar = (SeekBar) view.findViewById( + com.android.internal.R.id.seekbar); + seekBar.setOnSeekBarChangeListener(this); + seekBar.setMax(mMax); + seekBar.setProgress(mProgress); + seekBar.setEnabled(isEnabled()); + } + + @Override + public CharSequence getSummary() { + return null; + } + + @Override + protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { + setProgress(restoreValue ? getPersistedInt(mProgress) + : (Integer) defaultValue); + } + + @Override + public boolean onKey(View v, int keyCode, KeyEvent event) { + if (event.getAction() != KeyEvent.ACTION_UP) { + if (keyCode == KeyEvent.KEYCODE_PLUS + || keyCode == KeyEvent.KEYCODE_EQUALS) { + setProgress(getProgress() + 1); + return true; + } + if (keyCode == KeyEvent.KEYCODE_MINUS) { + setProgress(getProgress() - 1); + return true; + } + } + return false; + } + + public void setMax(int max) { + if (max != mMax) { + mMax = max; + notifyChanged(); + } + } + + public void setProgress(int progress) { + setProgress(progress, true); + } + + private void setProgress(int progress, boolean notifyChanged) { + if (progress > mMax) { + progress = mMax; + } + if (progress < 0) { + progress = 0; + } + if (progress != mProgress) { + mProgress = progress; + persistInt(progress); + if (notifyChanged) { + notifyChanged(); + } + } + } - setDialogLayoutResource(com.android.internal.R.layout.seekbar_dialog); - createActionButtons(); + public int getProgress() { + return mProgress; + } + + /** + * Persist the seekBar's progress value if callChangeListener + * returns true, otherwise set the seekBar's progress to the stored value + */ + void syncProgress(SeekBar seekBar) { + int progress = seekBar.getProgress(); + if (progress != mProgress) { + if (callChangeListener(progress)) { + setProgress(progress, false); + } else { + seekBar.setProgress(mProgress); + } + } + } + + @Override + public void onProgressChanged( + SeekBar seekBar, int progress, boolean fromUser) { + if (fromUser && !mTrackingTouch) { + syncProgress(seekBar); + } + } - // Steal the XML dialogIcon attribute's value - mMyIcon = getDialogIcon(); - setDialogIcon(null); + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + mTrackingTouch = true; } - // Allow subclasses to override the action buttons - public void createActionButtons() { - setPositiveButtonText(android.R.string.ok); - setNegativeButtonText(android.R.string.cancel); + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + mTrackingTouch = false; + if (seekBar.getProgress() != mProgress) { + syncProgress(seekBar); + } + } + + @Override + protected Parcelable onSaveInstanceState() { + /* + * Suppose a client uses this preference type without persisting. We + * must save the instance state so it is able to, for example, survive + * orientation changes. + */ + + final Parcelable superState = super.onSaveInstanceState(); + if (isPersistent()) { + // No need to save instance state since it's persistent + return superState; + } + + // Save the instance state + final SavedState myState = new SavedState(superState); + myState.progress = mProgress; + myState.max = mMax; + return myState; } @Override - protected void onBindDialogView(View view) { - super.onBindDialogView(view); - - final ImageView iconView = (ImageView) view.findViewById(android.R.id.icon); - if (mMyIcon != null) { - iconView.setImageDrawable(mMyIcon); - } else { - iconView.setVisibility(View.GONE); + protected void onRestoreInstanceState(Parcelable state) { + if (!state.getClass().equals(SavedState.class)) { + // Didn't save state for us in onSaveInstanceState + super.onRestoreInstanceState(state); + return; } + + // Restore the instance state + SavedState myState = (SavedState) state; + super.onRestoreInstanceState(myState.getSuperState()); + mProgress = myState.progress; + mMax = myState.max; + notifyChanged(); } - protected static SeekBar getSeekBar(View dialogView) { - return (SeekBar) dialogView.findViewById(com.android.internal.R.id.seekbar); + /** + * SavedState, a subclass of {@link BaseSavedState}, will store the state + * of MyPreference, a subclass of Preference. + * <p> + * It is important to always call through to super methods. + */ + private static class SavedState extends BaseSavedState { + int progress; + int max; + + public SavedState(Parcel source) { + super(source); + + // Restore the click counter + progress = source.readInt(); + max = source.readInt(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + + // Save the click counter + dest.writeInt(progress); + dest.writeInt(max); + } + + public SavedState(Parcelable superState) { + super(superState); + } + + @SuppressWarnings("unused") + public static final Parcelable.Creator<SavedState> CREATOR = + new Parcelable.Creator<SavedState>() { + public SavedState createFromParcel(Parcel in) { + return new SavedState(in); + } + + public SavedState[] newArray(int size) { + return new SavedState[size]; + } + }; } } diff --git a/core/java/android/preference/VolumePreference.java b/core/java/android/preference/VolumePreference.java index 3b12780..b48e8ce 100644 --- a/core/java/android/preference/VolumePreference.java +++ b/core/java/android/preference/VolumePreference.java @@ -38,19 +38,19 @@ import android.widget.SeekBar.OnSeekBarChangeListener; /** * @hide */ -public class VolumePreference extends SeekBarPreference implements +public class VolumePreference extends SeekBarDialogPreference implements PreferenceManager.OnActivityStopListener, View.OnKeyListener { private static final String TAG = "VolumePreference"; - + private int mStreamType; /** May be null if the dialog isn't visible. */ private SeekBarVolumizer mSeekBarVolumizer; - + public VolumePreference(Context context, AttributeSet attrs) { super(context, attrs); - + TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.VolumePreference, 0, 0); mStreamType = a.getInt(android.R.styleable.VolumePreference_streamType, 0); @@ -64,7 +64,7 @@ public class VolumePreference extends SeekBarPreference implements @Override protected void onBindDialogView(View view) { super.onBindDialogView(view); - + final SeekBar seekBar = (SeekBar) view.findViewById(com.android.internal.R.id.seekbar); mSeekBarVolumizer = new SeekBarVolumizer(getContext(), seekBar, mStreamType); @@ -105,7 +105,7 @@ public class VolumePreference extends SeekBarPreference implements @Override protected void onDialogClosed(boolean positiveResult) { super.onDialogClosed(positiveResult); - + if (!positiveResult && mSeekBarVolumizer != null) { mSeekBarVolumizer.revertVolume(); } @@ -222,16 +222,16 @@ public class VolumePreference extends SeekBarPreference implements private Context mContext; private Handler mHandler = new Handler(); - + private AudioManager mAudioManager; private int mStreamType; - private int mOriginalStreamVolume; + private int mOriginalStreamVolume; private Ringtone mRingtone; - + private int mLastProgress = -1; private SeekBar mSeekBar; private int mVolumeBeforeMute = -1; - + private ContentObserver mVolumeObserver = new ContentObserver(mHandler) { @Override public void onChange(boolean selfChange) { @@ -263,7 +263,7 @@ public class VolumePreference extends SeekBarPreference implements mOriginalStreamVolume = mAudioManager.getStreamVolume(mStreamType); seekBar.setProgress(mOriginalStreamVolume); seekBar.setOnSeekBarChangeListener(this); - + mContext.getContentResolver().registerContentObserver( System.getUriFor(System.VOLUME_SETTINGS[mStreamType]), false, mVolumeObserver); @@ -290,17 +290,17 @@ public class VolumePreference extends SeekBarPreference implements mContext.getContentResolver().unregisterContentObserver(mVolumeObserver); mSeekBar.setOnSeekBarChangeListener(null); } - + public void revertVolume() { mAudioManager.setStreamVolume(mStreamType, mOriginalStreamVolume, 0); } - + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) { if (!fromTouch) { return; } - + postSetVolume(progress); } @@ -310,7 +310,7 @@ public class VolumePreference extends SeekBarPreference implements mHandler.removeCallbacks(this); mHandler.post(this); } - + public void onStartTrackingTouch(SeekBar seekBar) { } @@ -319,7 +319,7 @@ public class VolumePreference extends SeekBarPreference implements startSample(); } } - + public void run() { mAudioManager.setStreamVolume(mStreamType, mLastProgress, 0); } @@ -334,7 +334,7 @@ public class VolumePreference extends SeekBarPreference implements mRingtone.play(); } } - + public void stopSample() { if (mRingtone != null) { mRingtone.stop(); @@ -344,7 +344,7 @@ public class VolumePreference extends SeekBarPreference implements public SeekBar getSeekBar() { return mSeekBar; } - + public void changeVolumeBy(int amount) { mSeekBar.incrementProgressBy(amount); if (!isSamplePlaying()) { diff --git a/core/java/android/provider/CalendarContract.java b/core/java/android/provider/CalendarContract.java index 3db1827..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/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java index 00e2998..1816066 100644 --- a/core/java/android/provider/ContactsContract.java +++ b/core/java/android/provider/ContactsContract.java @@ -1298,6 +1298,15 @@ public final class ContactsContract { public static final Uri CONTENT_VCARD_URI = Uri.withAppendedPath(CONTENT_URI, "as_vcard"); + /** + * Boolean parameter that may be used with {@link #CONTENT_VCARD_URI} + * and {@link #CONTENT_MULTI_VCARD_URI} to indicate that the returned + * vcard should not contain a photo. + * + * @hide + */ + public static final String QUERY_PARAMETER_VCARD_NO_PHOTO = "nophoto"; + /** * Base {@link Uri} for referencing multiple {@link Contacts} entry, * created by appending {@link #LOOKUP_KEY} using diff --git a/core/java/android/provider/Downloads.java b/core/java/android/provider/Downloads.java index 3c4bb79..0a8c3ca 100644 --- a/core/java/android/provider/Downloads.java +++ b/core/java/android/provider/Downloads.java @@ -17,6 +17,7 @@ package android.provider; import android.app.DownloadManager; +import android.net.NetworkPolicyManager; import android.net.Uri; /** @@ -547,6 +548,14 @@ public final class Downloads { } /** + * This download has been paused because requesting application has been + * blocked by {@link NetworkPolicyManager}. + * + * @hide + */ + public static final int STATUS_PAUSED_BY_POLICY = 189; + + /** * This download hasn't stated yet */ public static final int STATUS_PENDING = 190; diff --git a/core/java/android/speech/tts/SynthesisRequest.java b/core/java/android/speech/tts/SynthesisRequest.java index ef1704c..6398d3d 100644 --- a/core/java/android/speech/tts/SynthesisRequest.java +++ b/core/java/android/speech/tts/SynthesisRequest.java @@ -42,7 +42,7 @@ public final class SynthesisRequest { private int mSpeechRate; private int mPitch; - SynthesisRequest(String text, Bundle params) { + public SynthesisRequest(String text, Bundle params) { mText = text; // Makes a copy of params. mParams = new Bundle(params); diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java index 7d596df..40e9355 100755 --- a/core/java/android/speech/tts/TextToSpeech.java +++ b/core/java/android/speech/tts/TextToSpeech.java @@ -498,8 +498,7 @@ public class TextToSpeech { private int initTts() { String defaultEngine = getDefaultEngine(); String engine = defaultEngine; - if (!areDefaultsEnforced() && !TextUtils.isEmpty(mRequestedEngine) - && mEnginesHelper.isEngineEnabled(mRequestedEngine)) { + if (mEnginesHelper.isEngineInstalled(mRequestedEngine)) { engine = mRequestedEngine; } @@ -1080,12 +1079,12 @@ public class TextToSpeech { } /** - * Checks whether the user's settings should override settings requested by the calling - * application. + * Checks whether the user's settings should override settings requested + * by the calling application. As of the Ice cream sandwich release, + * user settings never forcibly override the app's settings. */ public boolean areDefaultsEnforced() { - return Settings.Secure.getInt(mContext.getContentResolver(), - Settings.Secure.TTS_USE_DEFAULTS, Engine.USE_DEFAULTS) == 1; + return false; } /** diff --git a/core/java/android/speech/tts/TextToSpeechService.java b/core/java/android/speech/tts/TextToSpeechService.java index 3eea6b7..7ea9373 100644 --- a/core/java/android/speech/tts/TextToSpeechService.java +++ b/core/java/android/speech/tts/TextToSpeechService.java @@ -191,11 +191,6 @@ public abstract class TextToSpeechService extends Service { protected abstract void onSynthesizeText(SynthesisRequest request, SynthesisCallback callback); - private boolean areDefaultsEnforced() { - return getSecureSettingInt(Settings.Secure.TTS_USE_DEFAULTS, - TextToSpeech.Engine.USE_DEFAULTS) == 1; - } - private int getDefaultSpeechRate() { return getSecureSettingInt(Settings.Secure.TTS_DEFAULT_RATE, Engine.DEFAULT_RATE); } @@ -504,13 +499,9 @@ public abstract class TextToSpeechService extends Service { } private void setRequestParams(SynthesisRequest request) { - if (areDefaultsEnforced()) { - request.setLanguage(getDefaultLanguage(), getDefaultCountry(), getDefaultVariant()); - request.setSpeechRate(getDefaultSpeechRate()); - } else { - request.setLanguage(getLanguage(), getCountry(), getVariant()); - request.setSpeechRate(getSpeechRate()); - } + request.setLanguage(getLanguage(), getCountry(), getVariant()); + request.setSpeechRate(getSpeechRate()); + request.setPitch(getPitch()); } @@ -749,13 +740,6 @@ public abstract class TextToSpeechService extends Service { return TextToSpeech.ERROR; } - if (areDefaultsEnforced()) { - if (isDefault(lang, country, variant)) { - return mDefaultAvailability; - } else { - return TextToSpeech.LANG_NOT_SUPPORTED; - } - } return onIsLanguageAvailable(lang, country, variant); } @@ -768,13 +752,6 @@ public abstract class TextToSpeechService extends Service { return TextToSpeech.ERROR; } - if (areDefaultsEnforced()) { - if (isDefault(lang, country, variant)) { - return mDefaultAvailability; - } else { - return TextToSpeech.LANG_NOT_SUPPORTED; - } - } return onLoadLanguage(lang, country, variant); } diff --git a/core/java/android/speech/tts/TtsEngines.java b/core/java/android/speech/tts/TtsEngines.java index 715894f..ed9e048 100644 --- a/core/java/android/speech/tts/TtsEngines.java +++ b/core/java/android/speech/tts/TtsEngines.java @@ -117,30 +117,10 @@ public class TtsEngines { return engines; } - /** - * Checks whether a given engine is enabled or not. Note that all system - * engines are enabled by default. - */ + // TODO: Used only by the settings app. Remove once + // the settings UI change has been finalized. public boolean isEngineEnabled(String engine) { - // System engines are enabled by default always. - EngineInfo info = getEngineInfo(engine); - if (info == null) { - // The engine is not installed, and therefore cannot - // be enabled. - return false; - } - - if (info.system) { - // All system engines are enabled by default. - return true; - } - - for (String enabled : getUserEnabledEngines()) { - if (engine.equals(enabled)) { - return true; - } - } - return false; + return isEngineInstalled(engine); } private boolean isSystemEngine(ServiceInfo info) { @@ -149,22 +129,14 @@ public class TtsEngines { } /** - * @return true if a given engine is installed on the system. Useful to deal - * with cases where an engine has been uninstalled by the user or removed - * for any other reason. + * @return true if a given engine is installed on the system. */ - private boolean isEngineInstalled(String engine) { + public boolean isEngineInstalled(String engine) { if (engine == null) { return false; } - for (EngineInfo info : getEngines()) { - if (engine.equals(info.name)) { - return true; - } - } - - return false; + return getEngineInfo(engine) != null; } private EngineInfo getEngineInfo(ResolveInfo resolve, PackageManager pm) { @@ -185,17 +157,6 @@ public class TtsEngines { return null; } - // Note that in addition to this list, all engines that are a part - // of the system are enabled by default. - private String[] getUserEnabledEngines() { - String str = Settings.Secure.getString(mContext.getContentResolver(), - Settings.Secure.TTS_ENABLED_PLUGINS); - if (TextUtils.isEmpty(str)) { - return new String[0]; - } - return str.split(" "); - } - private static class EngineInfoComparator implements Comparator<EngineInfo> { private EngineInfoComparator() { } diff --git a/core/java/android/util/FinitePool.java b/core/java/android/util/FinitePool.java index 4ae21ad..b30f2bf 100644 --- a/core/java/android/util/FinitePool.java +++ b/core/java/android/util/FinitePool.java @@ -20,6 +20,8 @@ package android.util; * @hide */ class FinitePool<T extends Poolable<T>> implements Pool<T> { + private static final String LOG_TAG = "FinitePool"; + /** * Factory used to create new pool objects */ @@ -77,15 +79,16 @@ class FinitePool<T extends Poolable<T>> implements Pool<T> { } public void release(T element) { - if (element.isPooled()) { - throw new IllegalArgumentException("Element already in the pool."); - } - if (mInfinite || mPoolCount < mLimit) { - mPoolCount++; - element.setNextPoolable(mRoot); - element.setPooled(true); - mRoot = element; + if (!element.isPooled()) { + if (mInfinite || mPoolCount < mLimit) { + mPoolCount++; + element.setNextPoolable(mRoot); + element.setPooled(true); + mRoot = element; + } + mManager.onReleased(element); + } else { + Log.w(LOG_TAG, "Element is already in pool: " + element); } - mManager.onReleased(element); } } diff --git a/core/java/android/util/LocaleUtil.java b/core/java/android/util/LocaleUtil.java new file mode 100644 index 0000000..74a930f --- /dev/null +++ b/core/java/android/util/LocaleUtil.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.util; + +import java.util.Locale; + +import libcore.icu.ICU; + +/** + * Various utilities for Locales + * + * @hide + */ +public class LocaleUtil { + + private LocaleUtil() { /* cannot be instantiated */ } + + /** + * @hide Do not use. Implementation not finished. + */ + public static final int TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE = -1; + + /** + * @hide Do not use. Implementation not finished. + */ + public static final int TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE = 0; + + /** + * @hide Do not use. Implementation not finished. + */ + public static final int TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE = 1; + + private static final char UNDERSCORE_CHAR = '_'; + + private static String ARAB_SCRIPT_SUBTAG = "Arab"; + private static String HEBR_SCRIPT_SUBTAG = "Hebr"; + + /** + * Return the layout direction for a given Locale + * + * @param locale the Locale for which we want the layout direction. Can be null. + * @return the layout direction. This may be one of: + * {@link #TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE} or + * {@link #TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE} or + * {@link #TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE}. + * + * Be careful: this code will need to be changed when vertical scripts will be supported + * + * @hide + */ + public static int getLayoutDirectionFromLocale(Locale locale) { + if (locale == null || locale.equals(Locale.ROOT)) { + return TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE; + } + + final String scriptSubtag = ICU.getScript(ICU.addLikelySubtags(locale.toString())); + if (scriptSubtag == null) return getLayoutDirectionFromFirstChar(locale); + + if (scriptSubtag.equalsIgnoreCase(ARAB_SCRIPT_SUBTAG) || + scriptSubtag.equalsIgnoreCase(HEBR_SCRIPT_SUBTAG)) { + return TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE; + } + return TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE; + } + + /** + * Fallback algorithm to detect the locale direction. Rely on the fist char of the + * localized locale name. This will not work if the localized locale name is in English + * (this is the case for ICU 4.4 and "Urdu" script) + * + * @param locale + * @return the layout direction. This may be one of: + * {@link #TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE} or + * {@link #TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE} or + * {@link #TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE}. + * + * Be careful: this code will need to be changed when vertical scripts will be supported + * + * @hide + */ + private static int getLayoutDirectionFromFirstChar(Locale locale) { + switch(Character.getDirectionality(locale.getDisplayName(locale).charAt(0))) { + case Character.DIRECTIONALITY_LEFT_TO_RIGHT: + return TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE; + case Character.DIRECTIONALITY_RIGHT_TO_LEFT: + case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC: + return TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE; + default: + return TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE; + } + } +} diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java index 383bfb3..5216c49 100644 --- a/core/java/android/view/GLES20Canvas.java +++ b/core/java/android/view/GLES20Canvas.java @@ -29,6 +29,7 @@ import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Region; import android.graphics.Shader; +import android.graphics.SurfaceTexture; import android.graphics.TemporaryBuffer; import android.text.GraphicsOperations; import android.text.SpannableString; @@ -163,7 +164,7 @@ class GLES20Canvas extends HardwareCanvas { static native int nCreateTextureLayer(int[] layerInfo); static native int nCreateLayer(int width, int height, boolean isOpaque, int[] layerInfo); static native void nResizeLayer(int layerId, int width, int height, int[] layerInfo); - static native void nUpdateTextureLayer(int layerId, int width, int height, int surface); + static native void nUpdateTextureLayer(int layerId, int width, int height, SurfaceTexture surface); static native void nDestroyLayer(int layerId); static native void nDestroyLayerDeferred(int layerId); static native boolean nCopyLayer(int layerId, int bitmap); diff --git a/core/java/android/view/GLES20TextureLayer.java b/core/java/android/view/GLES20TextureLayer.java index fcf421b..063eee7 100644 --- a/core/java/android/view/GLES20TextureLayer.java +++ b/core/java/android/view/GLES20TextureLayer.java @@ -70,7 +70,7 @@ class GLES20TextureLayer extends GLES20Layer { return mSurface; } - void update(int width, int height, int surface) { - GLES20Canvas.nUpdateTextureLayer(mLayer, width, height, surface); + void update(int width, int height) { + GLES20Canvas.nUpdateTextureLayer(mLayer, width, height, mSurface); } } diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java index 5944bd4..5ceb12a 100644 --- a/core/java/android/view/HardwareRenderer.java +++ b/core/java/android/view/HardwareRenderer.java @@ -194,7 +194,7 @@ public abstract class HardwareRenderer { * * @return A {@link SurfaceTexture} */ - abstract SurfaceTexture createSuraceTexture(HardwareLayer layer); + abstract SurfaceTexture createSurfaceTexture(HardwareLayer layer); /** * Updates the specified layer. @@ -202,10 +202,8 @@ public abstract class HardwareRenderer { * @param layer The hardware layer to update * @param width The layer's width * @param height The layer's height - * @param surface The surface to update */ - abstract void updateTextureLayer(HardwareLayer layer, int width, int height, - SurfaceTexture surface); + abstract void updateTextureLayer(HardwareLayer layer, int width, int height); /** * Copies the content of the specified layer into the specified bitmap. @@ -815,14 +813,13 @@ public abstract class HardwareRenderer { } @Override - SurfaceTexture createSuraceTexture(HardwareLayer layer) { + SurfaceTexture createSurfaceTexture(HardwareLayer layer) { return ((GLES20TextureLayer) layer).getSurfaceTexture(); } @Override - void updateTextureLayer(HardwareLayer layer, int width, int height, - SurfaceTexture surface) { - ((GLES20TextureLayer) layer).update(width, height, surface.mSurfaceTexture); + void updateTextureLayer(HardwareLayer layer, int width, int height) { + ((GLES20TextureLayer) layer).update(width, height); } @Override diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java index 4daa892..164c657 100644 --- a/core/java/android/view/TextureView.java +++ b/core/java/android/view/TextureView.java @@ -232,7 +232,7 @@ public class TextureView extends View { protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); if (mSurface != null) { - nSetDefaultBufferSize(mSurface.mSurfaceTexture, getWidth(), getHeight()); + nSetDefaultBufferSize(mSurface, getWidth(), getHeight()); if (mListener != null) { mListener.onSurfaceTextureSizeChanged(mSurface, getWidth(), getHeight()); } @@ -247,8 +247,8 @@ public class TextureView extends View { if (mLayer == null) { mLayer = mAttachInfo.mHardwareRenderer.createHardwareLayer(); - mSurface = mAttachInfo.mHardwareRenderer.createSuraceTexture(mLayer); - nSetDefaultBufferSize(mSurface.mSurfaceTexture, getWidth(), getHeight()); + mSurface = mAttachInfo.mHardwareRenderer.createSurfaceTexture(mLayer); + nSetDefaultBufferSize(mSurface, getWidth(), getHeight()); mUpdateListener = new SurfaceTexture.OnFrameAvailableListener() { @Override @@ -290,7 +290,7 @@ public class TextureView extends View { return; } - mAttachInfo.mHardwareRenderer.updateTextureLayer(mLayer, getWidth(), getHeight(), mSurface); + mAttachInfo.mHardwareRenderer.updateTextureLayer(mLayer, getWidth(), getHeight()); invalidate(); } @@ -447,5 +447,5 @@ public class TextureView extends View { public void onSurfaceTextureDestroyed(SurfaceTexture surface); } - private static native void nSetDefaultBufferSize(int surfaceTexture, int width, int height); + private static native void nSetDefaultBufferSize(SurfaceTexture surfaceTexture, int width, int height); } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 1dfb858..b0e651a 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -17,6 +17,7 @@ package android.view; import android.util.FloatProperty; +import android.util.LocaleUtil; import android.util.Property; import com.android.internal.R; import com.android.internal.util.Predicate; @@ -8772,18 +8773,8 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit * @return true if a Locale is corresponding to a RTL script. */ private static boolean isLayoutDirectionRtl(Locale locale) { - if (locale == null || locale.equals(Locale.ROOT)) return false; - // Be careful: this code will need to be changed when vertical scripts will be supported - // OR if ICU4C is updated to have the "likelySubtags" file - switch(Character.getDirectionality(locale.getDisplayName(locale).charAt(0))) { - case Character.DIRECTIONALITY_LEFT_TO_RIGHT: - return false; - case Character.DIRECTIONALITY_RIGHT_TO_LEFT: - case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC: - return true; - default: - return false; - } + return (LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE == + LocaleUtil.getLayoutDirectionFromLocale(locale)); } /** diff --git a/core/java/android/view/ViewAncestor.java b/core/java/android/view/ViewAncestor.java index 914973e..ba3ae58 100644 --- a/core/java/android/view/ViewAncestor.java +++ b/core/java/android/view/ViewAncestor.java @@ -4407,7 +4407,7 @@ public final class ViewAncestor extends Handler implements ViewParent, predicate.init(accessibilityId); View root = ViewAncestor.this.mView; View target = root.findViewByPredicate(predicate); - if (target != null) { + if (target != null && target.isShown()) { info = target.createAccessibilityNodeInfo(); } } finally { @@ -4439,7 +4439,7 @@ public final class ViewAncestor extends Handler implements ViewParent, try { View root = ViewAncestor.this.mView; View target = root.findViewById(viewId); - if (target != null) { + if (target != null && target.isShown()) { info = target.createAccessibilityNodeInfo(); } } finally { @@ -4486,7 +4486,7 @@ public final class ViewAncestor extends Handler implements ViewParent, root = ViewAncestor.this.mView; } - if (root == null) { + if (root == null || !root.isShown()) { return; } @@ -4501,7 +4501,9 @@ public final class ViewAncestor extends Handler implements ViewParent, final int viewCount = foundViews.size(); for (int i = 0; i < viewCount; i++) { View foundView = foundViews.get(i); - infos.add(foundView.createAccessibilityNodeInfo()); + if (foundView.isShown()) { + infos.add(foundView.createAccessibilityNodeInfo()); + } } } finally { try { @@ -4611,7 +4613,8 @@ public final class ViewAncestor extends Handler implements ViewParent, return null; } mFindByAccessibilityIdPredicate.init(accessibilityId); - return root.findViewByPredicate(mFindByAccessibilityIdPredicate); + View foundView = root.findViewByPredicate(mFindByAccessibilityIdPredicate); + return (foundView != null && foundView.isShown()) ? foundView : null; } private final class FindByAccessibilitytIdPredicate implements Predicate<View> { diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 57ee8a0..a6bce75 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -2023,10 +2023,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager @Override public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); - for (int i = 0, count = mChildrenCount; i < count; i++) { View child = mChildren[i]; - info.addChild(child); + if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) { + info.addChild(child); + } } } diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java index 9eddf23..a3de285 100644 --- a/core/java/android/view/ViewPropertyAnimator.java +++ b/core/java/android/view/ViewPropertyAnimator.java @@ -349,7 +349,7 @@ public class ViewPropertyAnimator { } } mPendingAnimations.clear(); - mView.getHandler().removeCallbacks(mAnimationStarter); + mView.removeCallbacks(mAnimationStarter); } /** @@ -705,7 +705,7 @@ public class ViewPropertyAnimator { NameValuesHolder nameValuePair = new NameValuesHolder(constantName, startValue, byValue); mPendingAnimations.add(nameValuePair); - mView.getHandler().removeCallbacks(mAnimationStarter); + mView.removeCallbacks(mAnimationStarter); mView.post(mAnimationStarter); } diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java index a730018..2410eb2 100644 --- a/core/java/android/widget/CompoundButton.java +++ b/core/java/android/widget/CompoundButton.java @@ -28,6 +28,7 @@ import android.util.AttributeSet; import android.view.Gravity; import android.view.ViewDebug; import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityNodeInfo; /** * <p> @@ -214,6 +215,12 @@ public abstract class CompoundButton extends Button implements Checkable { } @Override + public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { + super.onInitializeAccessibilityNodeInfo(info); + info.setChecked(mChecked); + } + + @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java index 092c2f7..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) { @@ -844,8 +843,8 @@ public class GridLayout extends ViewGroup { int pWidth = getMeasurement(view, true, PRF); int pHeight = getMeasurement(view, false, PRF); - Alignment hAlignment = columnGroup.alignment; - Alignment vAlignment = rowGroup.alignment; + Alignment hAlign = columnGroup.alignment; + Alignment vAlign = rowGroup.alignment; int dx, dy; @@ -853,8 +852,9 @@ public class GridLayout extends ViewGroup { Bounds rowBounds = mVerticalAxis.getGroupBounds().getValue(i); // Gravity offsets: the location of the alignment group relative to its cell group. - int c2ax = protect(hAlignment.getAlignmentValue(null, cellWidth - colBounds.size())); - int c2ay = protect(vAlignment.getAlignmentValue(null, cellHeight - rowBounds.size())); + int type = PRF; + int c2ax = protect(hAlign.getAlignmentValue(null, cellWidth - colBounds.size(), type)); + int c2ay = protect(vAlign.getAlignmentValue(null, cellHeight - rowBounds.size(), type)); if (mMarginsIncludedInAlignment) { int leftMargin = getMargin(view, true, true); @@ -863,12 +863,12 @@ public class GridLayout extends ViewGroup { int bottomMargin = getMargin(view, false, false); // Same calculation as getMeasurementIncludingMargin() - int measuredWidth = leftMargin + pWidth + rightMargin; - int measuredHeight = topMargin + pHeight + bottomMargin; + int mWidth = leftMargin + pWidth + rightMargin; + int mHeight = topMargin + pHeight + bottomMargin; // Alignment offsets: the location of the view relative to its alignment group. - int a2vx = colBounds.before - hAlignment.getAlignmentValue(view, measuredWidth); - int a2vy = rowBounds.before - vAlignment.getAlignmentValue(view, measuredHeight); + int a2vx = colBounds.before - hAlign.getAlignmentValue(view, mWidth, type); + int a2vy = rowBounds.before - vAlign.getAlignmentValue(view, mHeight, type); dx = c2ax + a2vx + leftMargin; dy = c2ay + a2vy + topMargin; @@ -877,15 +877,15 @@ public class GridLayout extends ViewGroup { cellHeight -= topMargin + bottomMargin; } else { // Alignment offsets: the location of the view relative to its alignment group. - int a2vx = colBounds.before - hAlignment.getAlignmentValue(view, pWidth); - int a2vy = rowBounds.before - vAlignment.getAlignmentValue(view, pHeight); + int a2vx = colBounds.before - hAlign.getAlignmentValue(view, pWidth, type); + int a2vy = rowBounds.before - vAlign.getAlignmentValue(view, pHeight, type); dx = c2ax + a2vx; dy = c2ay + a2vy; } - int width = hAlignment.getSizeInCell(view, pWidth, cellWidth); - int height = vAlignment.getSizeInCell(view, pHeight, cellHeight); + int width = hAlign.getSizeInCell(view, pWidth, cellWidth, type); + int height = vAlign.getSizeInCell(view, pHeight, cellHeight, type); int cx = paddingLeft + x1 + dx; int cy = paddingTop + y1 + dy; @@ -1003,7 +1003,7 @@ public class GridLayout extends ViewGroup { int size = getMeasurementIncludingMargin(c, horizontal, PRF); // todo test this works correctly when the returned value is UNDEFINED - int before = g.alignment.getAlignmentValue(c, size); + int before = g.alignment.getAlignmentValue(c, size, PRF); bounds.include(before, size - before); } } @@ -1459,6 +1459,7 @@ public class GridLayout extends ViewGroup { spanSizes = null; leadingMargins = null; trailingMargins = null; + arcs = null; minima = null; weights = null; locations = null; @@ -2156,57 +2157,59 @@ public class GridLayout extends ViewGroup { * {@link Group#alignment alignment}. Overall placement of the view in the cell * group is specified by the two alignments which act along each axis independently. * <p> - * An Alignment implementation must define the {@link #getAlignmentValue(View, int)} + * An Alignment implementation must define {@link #getAlignmentValue(View, int, int)}, * to return the appropriate value for the type of alignment being defined. * The enclosing algorithms position the children - * so that the values returned from the alignment + * so that the locations defined by the alignmnet values * are the same for all of the views in a group. * <p> * The GridLayout class defines the most common alignments used in general layout: * {@link #TOP}, {@link #LEFT}, {@link #BOTTOM}, {@link #RIGHT}, {@link #CENTER}, {@link * #BASELINE} and {@link #FILL}. */ - public static interface Alignment { + public static abstract class Alignment { /** * Returns an alignment value. In the case of vertical alignments the value * returned should indicate the distance from the top of the view to the * alignment location. * For horizontal alignments measurement is made from the left edge of the component. * - * @param view the view to which this alignment should be applied - * @param viewSize the measured size of the view - * @return the alignment value + * @param view the view to which this alignment should be applied + * @param viewSize the measured size of the view + * @param measurementType the type of measurement that should be made + * + * @return the alignment value */ - public int getAlignmentValue(View view, int viewSize); + public abstract int getAlignmentValue(View view, int viewSize, int measurementType); /** * Returns the size of the view specified by this alignment. * In the case of vertical alignments this method should return a height; for * horizontal alignments this method should return the width. + * <p> + * The default implementation returns {@code viewSize}. + * + * @param view the view to which this alignment should be applied + * @param viewSize the measured size of the view + * @param cellSize the size of the cell into which this view will be placed + * @param measurementType the type of measurement that should be made * - * @param view the view to which this alignment should be applied - * @param viewSize the measured size of the view - * @param cellSize the size of the cell into which this view will be placed - * @return the aligned size + * @return the aligned size */ - public int getSizeInCell(View view, int viewSize, int cellSize); - } - - private static abstract class AbstractAlignment implements Alignment { - public int getSizeInCell(View view, int viewSize, int cellSize) { + public int getSizeInCell(View view, int viewSize, int cellSize, int measurementType) { return viewSize; } } - private static final Alignment LEADING = new AbstractAlignment() { - public int getAlignmentValue(View view, int viewSize) { + private static final Alignment LEADING = new Alignment() { + public int getAlignmentValue(View view, int viewSize, int measurementType) { return 0; } }; - private static final Alignment TRAILING = new AbstractAlignment() { - public int getAlignmentValue(View view, int viewSize) { + private static final Alignment TRAILING = new Alignment() { + public int getAlignmentValue(View view, int viewSize, int measurementType) { return viewSize; } }; @@ -2240,8 +2243,8 @@ public class GridLayout extends ViewGroup { * This constant may be used in both {@link LayoutParams#rowGroup rowGroups} and {@link * LayoutParams#columnGroup columnGroups}. */ - public static final Alignment CENTER = new AbstractAlignment() { - public int getAlignmentValue(View view, int viewSize) { + public static final Alignment CENTER = new Alignment() { + public int getAlignmentValue(View view, int viewSize, int measurementType) { return viewSize >> 1; } }; @@ -2253,8 +2256,8 @@ public class GridLayout extends ViewGroup { * * @see View#getBaseline() */ - public static final Alignment BASELINE = new AbstractAlignment() { - public int getAlignmentValue(View view, int height) { + public static final Alignment BASELINE = new Alignment() { + public int getAlignmentValue(View view, int viewSize, int measurementType) { if (view == null) { return UNDEFINED; } @@ -2274,12 +2277,13 @@ public class GridLayout extends ViewGroup { * {@link LayoutParams#columnGroup columnGroups}. */ public static final Alignment FILL = new Alignment() { - public int getAlignmentValue(View view, int viewSize) { + public int getAlignmentValue(View view, int viewSize, int measurementType) { return UNDEFINED; } - public int getSizeInCell(View view, int viewSize, int cellSize) { + @Override + public int getSizeInCell(View view, int viewSize, int cellSize, int measurementType) { return cellSize; } }; -}
\ No newline at end of file +} diff --git a/core/java/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/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl index 2ff0413..c11fc10 100644 --- a/core/java/com/android/internal/statusbar/IStatusBar.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl @@ -35,5 +35,6 @@ oneway interface IStatusBar void setImeWindowStatus(in IBinder token, int vis, int backDisposition); void setHardKeyboardStatus(boolean available, boolean enabled); void userActivity(); + void toggleRecentApps(); } diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl index 3f2b1ef..a9e5057 100644 --- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl @@ -47,4 +47,5 @@ interface IStatusBarService void setSystemUiVisibility(int vis); void setHardKeyboardEnabled(boolean enabled); void userActivity(); + void toggleRecentApps(); } diff --git a/core/java/com/android/internal/widget/DialogTitle.java b/core/java/com/android/internal/widget/DialogTitle.java index 125d2c5..cd165dc 100644 --- a/core/java/com/android/internal/widget/DialogTitle.java +++ b/core/java/com/android/internal/widget/DialogTitle.java @@ -54,15 +54,19 @@ public class DialogTitle extends TextView { if (ellipsisCount > 0) { setSingleLine(false); - TypedArray a = mContext.obtainStyledAttributes( - android.R.style.TextAppearance_Medium, - android.R.styleable.TextAppearance); + TypedArray a = mContext.obtainStyledAttributes(null, + android.R.styleable.TextAppearance, + android.R.attr.textAppearanceMedium, + android.R.style.TextAppearance_Medium); final int textSize = a.getDimensionPixelSize( android.R.styleable.TextAppearance_textSize, (int) (20 * getResources().getDisplayMetrics().density)); + final int textColor = a.getColor( + android.R.styleable.TextAppearance_textColor, 0xffffffff); // textSize is already expressed in pixels setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize); + setTextColor(textColor); setMaxLines(2); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index 7e82efb..e301e44 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -22,6 +22,7 @@ #include "GraphicsJNI.h" #include <nativehelper/JNIHelp.h> #include <android_runtime/AndroidRuntime.h> +#include <android_runtime/android_graphics_SurfaceTexture.h> #include <utils/ResourceTypes.h> #include <gui/SurfaceTexture.h> @@ -644,11 +645,13 @@ static void android_view_GLES20Canvas_resizeLayer(JNIEnv* env, jobject clazz, } static void android_view_GLES20Canvas_updateTextureLayer(JNIEnv* env, jobject clazz, - Layer* layer, jint width, jint height, SurfaceTexture* surface) { + Layer* layer, jint width, jint height, jobject surface) { float transform[16]; - surface->updateTexImage(); - surface->getTransformMatrix(transform); - GLenum renderTarget = surface->getCurrentTextureTarget(); + sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, surface)); + + surfaceTexture->updateTexImage(); + surfaceTexture->getTransformMatrix(transform); + GLenum renderTarget = surfaceTexture->getCurrentTextureTarget(); LayerRenderer::updateTextureLayer(layer, width, height, renderTarget, transform); } @@ -793,7 +796,8 @@ static JNINativeMethod gMethods[] = { { "nCreateLayer", "(IIZ[I)I", (void*) android_view_GLES20Canvas_createLayer }, { "nResizeLayer", "(III[I)V" , (void*) android_view_GLES20Canvas_resizeLayer }, { "nCreateTextureLayer", "([I)I", (void*) android_view_GLES20Canvas_createTextureLayer }, - { "nUpdateTextureLayer", "(IIII)V", (void*) android_view_GLES20Canvas_updateTextureLayer }, + { "nUpdateTextureLayer", "(IIILandroid/graphics/SurfaceTexture;)V", + (void*) android_view_GLES20Canvas_updateTextureLayer }, { "nDestroyLayer", "(I)V", (void*) android_view_GLES20Canvas_destroyLayer }, { "nDestroyLayerDeferred", "(I)V", (void*) android_view_GLES20Canvas_destroyLayerDeferred }, { "nDrawLayer", "(IIFFI)V", (void*) android_view_GLES20Canvas_drawLayer }, diff --git a/core/jni/android_view_TextureView.cpp b/core/jni/android_view_TextureView.cpp index c5d86c8..b046b23 100644 --- a/core/jni/android_view_TextureView.cpp +++ b/core/jni/android_view_TextureView.cpp @@ -17,6 +17,7 @@ #include "jni.h" #include <nativehelper/JNIHelp.h> #include <android_runtime/AndroidRuntime.h> +#include <android_runtime/android_graphics_SurfaceTexture.h> #include <gui/SurfaceTexture.h> @@ -27,10 +28,10 @@ namespace android { // ---------------------------------------------------------------------------- static void android_view_TextureView_setDefaultBufferSize(JNIEnv* env, jobject, - jint surfaceTexture, jint width, jint height) { + jobject surface, jint width, jint height) { - sp<SurfaceTexture> surface = reinterpret_cast<SurfaceTexture*>(surfaceTexture); - surface->setDefaultBufferSize(width, height); + sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, surface)); + surfaceTexture->setDefaultBufferSize(width, height); } // ---------------------------------------------------------------------------- @@ -40,7 +41,8 @@ static void android_view_TextureView_setDefaultBufferSize(JNIEnv* env, jobject, const char* const kClassPathName = "android/view/TextureView"; static JNINativeMethod gMethods[] = { - { "nSetDefaultBufferSize", "(III)V", (void*) android_view_TextureView_setDefaultBufferSize } + { "nSetDefaultBufferSize", "(Landroid/graphics/SurfaceTexture;II)V", + (void*) android_view_TextureView_setDefaultBufferSize } }; int register_android_view_TextureView(JNIEnv* env) { diff --git a/core/jni/com_google_android_gles_jni_EGLImpl.cpp b/core/jni/com_google_android_gles_jni_EGLImpl.cpp index f777527..02974f9 100644 --- a/core/jni/com_google_android_gles_jni_EGLImpl.cpp +++ b/core/jni/com_google_android_gles_jni_EGLImpl.cpp @@ -18,6 +18,7 @@ #include "JNIHelp.h" #include <android_runtime/AndroidRuntime.h> #include <android_runtime/android_view_Surface.h> +#include <android_runtime/android_graphics_SurfaceTexture.h> #include <utils/misc.h> #include <EGL/egl.h> @@ -323,7 +324,7 @@ not_valid_surface: } static jint jni_eglCreateWindowSurfaceTexture(JNIEnv *_env, jobject _this, jobject display, - jobject config, jint native_window, jintArray attrib_list) { + jobject config, jobject native_window, jintArray attrib_list) { if (display == NULL || config == NULL || !validAttribList(_env, attrib_list)) { jniThrowException(_env, "java/lang/IllegalArgumentException", NULL); @@ -339,7 +340,7 @@ not_valid_surface: return 0; } - sp<SurfaceTexture> surfaceTexture = reinterpret_cast<SurfaceTexture*>(native_window); + sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(_env, native_window)); window = new SurfaceTextureClient(surfaceTexture); if (window == NULL) @@ -540,7 +541,7 @@ static JNINativeMethod methods[] = { {"_eglCreatePbufferSurface","(" DISPLAY CONFIG "[I)I", (void*)jni_eglCreatePbufferSurface }, {"_eglCreatePixmapSurface", "(" SURFACE DISPLAY CONFIG OBJECT "[I)V", (void*)jni_eglCreatePixmapSurface }, {"_eglCreateWindowSurface", "(" DISPLAY CONFIG OBJECT "[I)I", (void*)jni_eglCreateWindowSurface }, -{"_eglCreateWindowSurfaceTexture", "(" DISPLAY CONFIG "I[I)I", (void*)jni_eglCreateWindowSurfaceTexture }, +{"_eglCreateWindowSurfaceTexture", "(" DISPLAY CONFIG OBJECT "[I)I", (void*)jni_eglCreateWindowSurfaceTexture }, {"eglDestroyContext", "(" DISPLAY CONTEXT ")Z", (void*)jni_eglDestroyContext }, {"eglDestroySurface", "(" DISPLAY SURFACE ")Z", (void*)jni_eglDestroySurface }, {"eglMakeCurrent", "(" DISPLAY SURFACE SURFACE CONTEXT")Z", (void*)jni_eglMakeCurrent }, diff --git a/core/res/res/drawable-hdpi/dialog_bottom_holo_dark.9.png b/core/res/res/drawable-hdpi/dialog_bottom_holo_dark.9.png Binary files differindex 32c2c97..5225a81 100644 --- a/core/res/res/drawable-hdpi/dialog_bottom_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/dialog_bottom_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/dialog_bottom_holo_light.9.png b/core/res/res/drawable-hdpi/dialog_bottom_holo_light.9.png Binary files differindex f1cba06..2e7e973 100644 --- a/core/res/res/drawable-hdpi/dialog_bottom_holo_light.9.png +++ b/core/res/res/drawable-hdpi/dialog_bottom_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/dialog_full_holo_dark.9.png b/core/res/res/drawable-hdpi/dialog_full_holo_dark.9.png Binary files differindex 08b163a..4591627 100644 --- a/core/res/res/drawable-hdpi/dialog_full_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/dialog_full_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/dialog_full_holo_light.9.png b/core/res/res/drawable-hdpi/dialog_full_holo_light.9.png Binary files differindex 77ec017..9cf1826 100644 --- a/core/res/res/drawable-hdpi/dialog_full_holo_light.9.png +++ b/core/res/res/drawable-hdpi/dialog_full_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/dialog_middle_holo_dark.9.png b/core/res/res/drawable-hdpi/dialog_middle_holo_dark.9.png Binary files differindex 029f186..a47ef40 100644 --- a/core/res/res/drawable-hdpi/dialog_middle_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/dialog_middle_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/dialog_middle_holo_light.9.png b/core/res/res/drawable-hdpi/dialog_middle_holo_light.9.png Binary files differindex ee1054e..9b50c73 100644 --- a/core/res/res/drawable-hdpi/dialog_middle_holo_light.9.png +++ b/core/res/res/drawable-hdpi/dialog_middle_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/dialog_top_holo_dark.9.png b/core/res/res/drawable-hdpi/dialog_top_holo_dark.9.png Binary files differindex acbd7cf..a0d36de 100644 --- a/core/res/res/drawable-hdpi/dialog_top_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/dialog_top_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/dialog_top_holo_light.9.png b/core/res/res/drawable-hdpi/dialog_top_holo_light.9.png Binary files differindex b7ddbb4..805b956 100644 --- a/core/res/res/drawable-hdpi/dialog_top_holo_light.9.png +++ b/core/res/res/drawable-hdpi/dialog_top_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/dialog_bottom_holo_dark.9.png b/core/res/res/drawable-mdpi/dialog_bottom_holo_dark.9.png Binary files differindex cc66804..a0bd4e3 100644 --- a/core/res/res/drawable-mdpi/dialog_bottom_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/dialog_bottom_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/dialog_bottom_holo_light.9.png b/core/res/res/drawable-mdpi/dialog_bottom_holo_light.9.png Binary files differindex bc734c8..12abcd2 100644 --- a/core/res/res/drawable-mdpi/dialog_bottom_holo_light.9.png +++ b/core/res/res/drawable-mdpi/dialog_bottom_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/dialog_full_holo_dark.9.png b/core/res/res/drawable-mdpi/dialog_full_holo_dark.9.png Binary files differindex 8603e93..adb8104 100644 --- a/core/res/res/drawable-mdpi/dialog_full_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/dialog_full_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/dialog_full_holo_light.9.png b/core/res/res/drawable-mdpi/dialog_full_holo_light.9.png Binary files differindex 65a318c..d7c6bbf 100644 --- a/core/res/res/drawable-mdpi/dialog_full_holo_light.9.png +++ b/core/res/res/drawable-mdpi/dialog_full_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/dialog_middle_holo_dark.9.png b/core/res/res/drawable-mdpi/dialog_middle_holo_dark.9.png Binary files differindex e39a472..42cfc52 100644 --- a/core/res/res/drawable-mdpi/dialog_middle_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/dialog_middle_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/dialog_middle_holo_light.9.png b/core/res/res/drawable-mdpi/dialog_middle_holo_light.9.png Binary files differindex ec06c17..9a08e15 100644 --- a/core/res/res/drawable-mdpi/dialog_middle_holo_light.9.png +++ b/core/res/res/drawable-mdpi/dialog_middle_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/dialog_top_holo_dark.9.png b/core/res/res/drawable-mdpi/dialog_top_holo_dark.9.png Binary files differindex 32c49f2..5d86b2a 100644 --- a/core/res/res/drawable-mdpi/dialog_top_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/dialog_top_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/dialog_top_holo_light.9.png b/core/res/res/drawable-mdpi/dialog_top_holo_light.9.png Binary files differindex 7a2bf8d..ad22f5b 100644 --- a/core/res/res/drawable-mdpi/dialog_top_holo_light.9.png +++ b/core/res/res/drawable-mdpi/dialog_top_holo_light.9.png diff --git a/core/res/res/layout/alert_dialog_holo.xml b/core/res/res/layout/alert_dialog_holo.xml index 8ee91ca..1a3573e 100644 --- a/core/res/res/layout/alert_dialog_holo.xml +++ b/core/res/res/layout/alert_dialog_holo.xml @@ -32,12 +32,10 @@ android:orientation="vertical"> <ImageView android:id="@+id/titleDividerTop" android:layout_width="match_parent" - android:layout_height="4dip" + android:layout_height="1dip" android:visibility="gone" android:scaleType="fitXY" android:gravity="fill_horizontal" - android:paddingLeft="16dip" - android:paddingRight="16dip" android:src="@android:drawable/divider_strong_holo" /> <LinearLayout android:id="@+id/title_template" android:layout_width="match_parent" @@ -45,15 +43,16 @@ android:orientation="horizontal" android:gravity="center_vertical|left" android:minHeight="@dimen/alert_dialog_title_height" - android:layout_marginLeft="32dip" - android:layout_marginRight="32dip"> + android:layout_marginLeft="16dip" + android:layout_marginRight="16dip"> <ImageView android:id="@+id/icon" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:paddingRight="16dip" + android:paddingRight="8dip" android:src="@null" /> <com.android.internal.widget.DialogTitle android:id="@+id/alertTitle" - style="?android:attr/textAppearanceMedium" + style="?android:attr/textAppearanceLarge" + android:textColor="@android:color/holo_blue" android:singleLine="true" android:ellipsize="end" android:layout_width="match_parent" @@ -61,12 +60,10 @@ </LinearLayout> <ImageView android:id="@+id/titleDivider" android:layout_width="match_parent" - android:layout_height="4dip" + android:layout_height="1dip" android:visibility="gone" android:scaleType="fitXY" android:gravity="fill_horizontal" - android:paddingLeft="16dip" - android:paddingRight="16dip" android:src="@android:drawable/divider_strong_holo" /> <!-- If the client uses a customTitle, it will be added here. --> </LinearLayout> @@ -79,10 +76,6 @@ <ScrollView android:id="@+id/scrollView" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginLeft="16dip" - android:layout_marginRight="16dip" - android:paddingTop="32dip" - android:paddingBottom="32dip" android:clipToPadding="false"> <TextView android:id="@+id/message" style="?android:attr/textAppearanceMedium" @@ -99,11 +92,7 @@ android:layout_weight="1"> <FrameLayout android:id="@+android:id/custom" android:layout_width="match_parent" - android:layout_height="wrap_content" - android:paddingTop="8dip" - android:paddingBottom="8dip" - android:paddingLeft="32dip" - android:paddingRight="32dip" /> + android:layout_height="wrap_content" /> </FrameLayout> <LinearLayout android:id="@+id/buttonPanel" @@ -113,27 +102,21 @@ android:orientation="vertical" android:divider="?android:attr/dividerHorizontal" android:showDividers="beginning" - android:dividerPadding="16dip"> + android:dividerPadding="0dip"> <LinearLayout style="?android:attr/buttonBarStyle" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" - android:paddingLeft="2dip" - android:paddingRight="2dip" + android:layoutDirection="locale" android:measureWithLargestChild="true"> - <LinearLayout android:id="@+id/leftSpacer" - android:layout_weight="0.25" - android:layout_width="0dip" - android:layout_height="wrap_content" - android:orientation="horizontal" - android:visibility="gone" /> - <Button android:id="@+id/button1" + <Button android:id="@+id/button2" android:layout_width="0dip" android:layout_gravity="left" android:layout_weight="1" android:maxLines="2" style="?android:attr/buttonBarButtonStyle" + android:textSize="14sp" android:minHeight="@dimen/alert_dialog_button_bar_height" android:layout_height="wrap_content" /> <Button android:id="@+id/button3" @@ -142,22 +125,18 @@ android:layout_weight="1" android:maxLines="2" style="?android:attr/buttonBarButtonStyle" + android:textSize="14sp" android:minHeight="@dimen/alert_dialog_button_bar_height" android:layout_height="wrap_content" /> - <Button android:id="@+id/button2" + <Button android:id="@+id/button1" android:layout_width="0dip" android:layout_gravity="right" android:layout_weight="1" android:maxLines="2" android:minHeight="@dimen/alert_dialog_button_bar_height" style="?android:attr/buttonBarButtonStyle" + android:textSize="14sp" android:layout_height="wrap_content" /> - <LinearLayout android:id="@+id/rightSpacer" - android:layout_width="0dip" - android:layout_weight="0.25" - android:layout_height="wrap_content" - android:orientation="horizontal" - android:visibility="gone" /> </LinearLayout> </LinearLayout> </LinearLayout> diff --git a/core/res/res/layout/dialog_custom_title_holo.xml b/core/res/res/layout/dialog_custom_title_holo.xml index 74b6070..5261553 100644 --- a/core/res/res/layout/dialog_custom_title_holo.xml +++ b/core/res/res/layout/dialog_custom_title_holo.xml @@ -23,18 +23,16 @@ This is an custom layout for a dialog. android:fitsSystemWindows="true"> <FrameLayout android:id="@android:id/title_container" android:layout_width="match_parent" - android:layout_height="60dip" + android:layout_height="@dimen/alert_dialog_title_height" android:layout_weight="0" android:gravity="center_vertical|left" style="?android:attr/windowTitleBackgroundStyle"> </FrameLayout> <ImageView android:id="@+id/titleDivider" android:layout_width="match_parent" - android:layout_height="4dip" + android:layout_height="1dip" android:scaleType="fitXY" android:gravity="fill_horizontal" - android:paddingLeft="16dip" - android:paddingRight="16dip" android:src="@android:drawable/divider_strong_holo" /> <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content" diff --git a/core/res/res/layout/dialog_title_holo.xml b/core/res/res/layout/dialog_title_holo.xml index 534dd8d..400ef60 100644 --- a/core/res/res/layout/dialog_title_holo.xml +++ b/core/res/res/layout/dialog_title_holo.xml @@ -26,17 +26,15 @@ enabled. <TextView android:id="@android:id/title" style="?android:attr/windowTitleStyle" android:layout_width="match_parent" android:layout_height="wrap_content" - android:minHeight="60dip" - android:paddingLeft="32dip" - android:paddingRight="32dip" + android:minHeight="@android:dimen/alert_dialog_title_height" + android:paddingLeft="16dip" + android:paddingRight="16dip" android:gravity="center_vertical|left" /> <ImageView android:id="@+id/titleDivider" android:layout_width="match_parent" - android:layout_height="4dip" + android:layout_height="1dip" android:scaleType="fitXY" android:gravity="fill_horizontal" - android:paddingLeft="16dip" - android:paddingRight="16dip" android:src="@android:drawable/divider_strong_holo" /> <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content" diff --git a/core/res/res/layout/dialog_title_icons_holo.xml b/core/res/res/layout/dialog_title_icons_holo.xml index a3cd3af..f780ab0 100644 --- a/core/res/res/layout/dialog_title_icons_holo.xml +++ b/core/res/res/layout/dialog_title_icons_holo.xml @@ -28,16 +28,16 @@ enabled. android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="center_vertical" - android:minHeight="60dip" - android:paddingLeft="32dip" - android:paddingRight="32dip"> + android:minHeight="@android:dimen/alert_dialog_title_height" + android:paddingLeft="16dip" + android:paddingRight="16dip"> <ImageView android:id="@+id/left_icon" android:layout_width="32dip" android:layout_height="32dip" android:scaleType="fitCenter" android:layout_marginRight="8dip" /> <TextView android:id="@android:id/title" - style="?android:attr/windowTitleStyle" + style="?android:attr/windowTitleStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="0" /> @@ -50,11 +50,9 @@ enabled. <ImageView android:id="@+id/titleDivider" android:layout_width="match_parent" - android:layout_height="4dip" + android:layout_height="1dip" android:scaleType="fitXY" android:gravity="fill_horizontal" - android:paddingLeft="16dip" - android:paddingRight="16dip" android:src="@android:drawable/divider_strong_holo" /> <FrameLayout diff --git a/core/res/res/layout/preference_widget_seekbar.xml b/core/res/res/layout/preference_widget_seekbar.xml new file mode 100644 index 0000000..e4cf86d --- /dev/null +++ b/core/res/res/layout/preference_widget_seekbar.xml @@ -0,0 +1,87 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2011 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<!-- Layout for a Preference in a PreferenceActivity. The + Preference is able to place a specific widget for its particular + type in the "widget_frame" layout. --> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:minHeight="?android:attr/listPreferredItemHeight" + android:gravity="center_vertical" + android:paddingRight="?android:attr/scrollbarSize"> + + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:gravity="center" + android:minWidth="@dimen/preference_icon_minWidth" + android:orientation="horizontal"> + <ImageView + android:id="@+android:id/icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:minWidth="48dp" + /> + </LinearLayout> + + <RelativeLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginLeft="16dip" + android:layout_marginRight="8dip" + android:layout_marginTop="6dip" + android:layout_marginBottom="6dip" + android:layout_weight="1"> + + <TextView android:id="@+android:id/title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:singleLine="true" + android:textAppearance="?android:attr/textAppearanceMedium" + android:ellipsize="marquee" + android:fadingEdge="horizontal" /> + + <TextView android:id="@+android:id/summary" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_below="@android:id/title" + android:layout_alignLeft="@android:id/title" + android:textAppearance="?android:attr/textAppearanceSmall" + android:textColor="?android:attr/textColorSecondary" + android:maxLines="4" /> + + <!-- Preference should place its actual preference widget here. --> + <LinearLayout android:id="@+android:id/widget_frame" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_below="@android:id/summary" + android:layout_alignLeft="@android:id/title" + android:minWidth="@dimen/preference_widget_width" + android:gravity="center" + android:orientation="vertical" /> + + <SeekBar android:id="@+android:id/seekbar" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_below="@android:id/summary" + android:layout_toRightOf="@android:id/widget_frame" + android:layout_alignParentRight="true" /> + + </RelativeLayout> + +</LinearLayout> diff --git a/core/res/res/layout/select_dialog_holo.xml b/core/res/res/layout/select_dialog_holo.xml index 7c95693..06a5d96 100644 --- a/core/res/res/layout/select_dialog_holo.xml +++ b/core/res/res/layout/select_dialog_holo.xml @@ -27,9 +27,6 @@ android:id="@+android:id/select_dialog_listview" android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_marginTop="5dip" - android:paddingLeft="16dip" - android:paddingRight="16dip" android:cacheColorHint="@null" android:divider="?android:attr/listDividerAlertDialog" android:scrollbars="vertical" diff --git a/core/res/res/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 3b4798e..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. --> @@ -389,9 +389,11 @@ <!-- Control the behavior when the user long presses the power button. 0 - Nothing 1 - Recent apps dialog - 2 - Recent apps activity in SystemUI + 2 - Recent apps view in SystemUI + This needs to match the constants in + policy/src/com/android/internal/policy/impl/PhoneWindowManager.java --> - <integer name="config_longPressOnHomeBehavior">1</integer> + <integer name="config_longPressOnHomeBehavior">2</integer> <!-- Array of light sensor LUX values to define our levels for auto backlight brightness support. The N entries of this array define N + 1 zones as follows: @@ -633,4 +635,11 @@ <!-- Set to true if the RSSI should always display CDMA signal strength even on EVDO --> <bool name="config_alwaysUseCdmaRssi">false</bool> + + <!-- If this value is true, duplicate Source/Destination port fields + in WDP header of some carriers OMADM wap push are supported. + ex: MSGTYPE-TotalSegments-CurrentSegment + -SourcePortDestPort-SourcePortDestPort-OMADM PDU + If false, not supported. --> + <bool name="config_duplicate_port_omadm_wappush">false</bool> </resources> 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/strings.xml b/core/res/res/values/strings.xml index 34bc6bb..d7b7dd0 100755 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -901,16 +901,16 @@ contact (address) data stored on your phone. Malicious applications can use this to erase or modify your contact data.</string> - <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> + <!-- Title of the read profile permission, listed so the user can decide whether to allow the application to read the user's personal profile data. [CHAR LIMIT=30] --> <string name="permlab_readProfile">read profile data</string> - <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> + <!-- Description of the read profile permission, listed so the user can decide whether to allow the application to read the user's personal profile data. [CHAR LIMIT=NONE] --> <string name="permdesc_readProfile" product="default">Allows an application to read all of your personal profile information. Malicious applications can use this to identify you and send your personal information to other people.</string> - <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> + <!-- Title of the write profile permission, listed so the user can decide whether to allow the application to write to the user's personal profile data. [CHAR LIMIT=30] --> <string name="permlab_writeProfile">write profile data</string> - <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> + <!-- Description of the write profile permission, listed so the user can decide whether to allow the application to write to the user's personal profile data. [CHAR LIMIT=NONE] --> <string name="permdesc_writeProfile" product="default">Allows an application to modify your personal profile information. Malicious applications can use this to erase or modify your profile data.</string> @@ -1790,6 +1790,9 @@ <string name="lockscreen_missing_sim_instructions">Please insert a SIM card.</string> <!-- Shown in the lock screen to ask the user to insert a SIM card when sim is missing or not readable. --> <string name="lockscreen_missing_sim_instructions_long">The SIM card is missing or not readable. Please insert a SIM card.</string> + <!-- Shown in the lock screen to inform the user to SIM card is permanently disabled. --> + <string name="lockscreen_permanent_disabled_sim_instructions">Your SIM card is permanently disabled.\n + Please contact your wireless service provider to obtain another SIM card.</string> <!-- Shown in the lock screen when there is emergency calls only mode. --> <string name="emergency_calls_only" msgid="2485604591272668370">Emergency calls only</string> diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml index 19b05c9..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/content/res/ConfigurationTest.java b/core/tests/coretests/src/android/content/res/ConfigurationTest.java deleted file mode 100644 index 54a5e4e..0000000 --- a/core/tests/coretests/src/android/content/res/ConfigurationTest.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.content.res; - -import java.util.Locale; - -import android.test.AndroidTestCase; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetNew; - -public class ConfigurationTest extends AndroidTestCase { - - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getLayoutDirectionFromLocale", - args = {Locale.class} - ) - public void testGetLayoutDirectionFromLocale() { - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(null)); - - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.ENGLISH)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.CANADA)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.CANADA_FRENCH)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.FRANCE)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.FRENCH)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.GERMAN)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.GERMANY)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.ITALIAN)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.ITALY)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.UK)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.US)); - - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.ROOT)); - - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.CHINA)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.CHINESE)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.JAPAN)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.JAPANESE)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.KOREA)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.KOREAN)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.PRC)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.SIMPLIFIED_CHINESE)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.TAIWAN)); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(Locale.TRADITIONAL_CHINESE)); - - Locale locale = new Locale("ar"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "AE"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "BH"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "DZ"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "EG"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "IQ"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "JO"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "KW"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "LB"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "LY"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "MA"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "OM"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "QA"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "SA"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "SD"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "SY"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "TN"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ar", "YE"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - - locale = new Locale("fa"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("fa", "AF"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("fa", "IR"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - - locale = new Locale("iw"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("iw", "IL"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("he"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("he", "IL"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - - // The following test will not pass until we are able to take care about the scrip subtag - // thru having the "likelySubTags" file into ICU4C -// locale = new Locale("pa_Arab"); -// assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, -// Configuration.getLayoutDirectionFromLocale(locale)); -// locale = new Locale("pa_Arab", "PK"); -// assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, -// Configuration.getLayoutDirectionFromLocale(locale)); - - locale = new Locale("ps"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - locale = new Locale("ps", "AF"); - assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, - Configuration.getLayoutDirectionFromLocale(locale)); - - // The following test will not work as the localized display name would be "Urdu" with ICU 4.4 - // We will need ICU 4.6 to get the correct localized display name -// locale = new Locale("ur"); -// assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, -// Configuration.getLayoutDirectionFromLocale(locale)); -// locale = new Locale("ur", "IN"); -// assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, -// Configuration.getLayoutDirectionFromLocale(locale)); -// locale = new Locale("ur", "PK"); -// assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, -// Configuration.getLayoutDirectionFromLocale(locale)); - - // The following test will not pass until we are able to take care about the scrip subtag - // thru having the "likelySubTags" file into ICU4C -// locale = new Locale("uz_Arab"); -// assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, -// Configuration.getLayoutDirectionFromLocale(locale)); -// locale = new Locale("uz_Arab", "AF"); -// assertEquals(Configuration.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, -// Configuration.getLayoutDirectionFromLocale(locale)); - } -} diff --git a/core/tests/coretests/src/android/util/LocaleUtilTest.java b/core/tests/coretests/src/android/util/LocaleUtilTest.java new file mode 100644 index 0000000..203781f --- /dev/null +++ b/core/tests/coretests/src/android/util/LocaleUtilTest.java @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.util; + +import java.util.Locale; + +import android.test.AndroidTestCase; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetNew; + +import static android.util.LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE; +import static android.util.LocaleUtil.TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE; + +public class LocaleUtilTest extends AndroidTestCase { + + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getLayoutDirectionFromLocale", + args = {Locale.class} + ) + public void testGetLayoutDirectionFromLocale() { + assertEquals(TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(null)); + + assertEquals(TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.ENGLISH)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.CANADA)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.CANADA_FRENCH)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.FRANCE)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.FRENCH)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.GERMAN)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.GERMANY)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.ITALIAN)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.ITALY)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.UK)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.US)); + + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.ROOT)); + + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.CHINA)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.CHINESE)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.JAPAN)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.JAPANESE)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.KOREA)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.KOREAN)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.PRC)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.SIMPLIFIED_CHINESE)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.TAIWAN)); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(Locale.TRADITIONAL_CHINESE)); + + Locale locale = new Locale("ar"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "AE"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "BH"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "DZ"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "EG"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "IQ"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "JO"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "KW"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "LB"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "LY"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "MA"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "OM"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "QA"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "SA"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "SD"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "SY"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "TN"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ar", "YE"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + + locale = new Locale("fa"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("fa", "AF"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("fa", "IR"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + + locale = new Locale("iw"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("iw", "IL"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("he"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("he", "IL"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + + locale = new Locale("pa_Arab"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("pa_Arab", "PK"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + + locale = new Locale("ps"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ps", "AF"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + + locale = new Locale("ur"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ur", "IN"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("ur", "PK"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + + locale = new Locale("uz_Arab"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + locale = new Locale("uz_Arab", "AF"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + + // Locale without a real language + locale = new Locale("zz"); + assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE, + LocaleUtil.getLayoutDirectionFromLocale(locale)); + } +} diff --git a/docs/html/resources/resources-data.js b/docs/html/resources/resources-data.js index 77aee46..097d004 100644 --- a/docs/html/resources/resources-data.js +++ b/docs/html/resources/resources-data.js @@ -407,6 +407,26 @@ var ANDROID_RESOURCES = [ } }, { + tags: ['sample', 'layout', 'ui', 'fragment', 'loader', 'new'], + path: 'samples/Support4Demos/index.html', + title: { + en: 'API 4+ Support Demos' + }, + description: { + en: 'A variety of small applications that demonstrate the use of the helper classes in the Android API 4+ Support Library (classes which work down to API level 4 or version 1.6 of the platform).' + } + }, + { + tags: ['sample', 'layout', 'ui', 'new'], + path: 'samples/Support13Demos/index.html', + title: { + en: 'API 13+ Support Demos' + }, + description: { + en: 'A variety of small applications that demonstrate the use of the helper classes in the Android API 13+ Support Library (classes which work down to API level 13 or version 3.2 of the platform).' + } + }, + { tags: ['sample', 'data', 'newfeature', 'accountsync'], path: 'samples/BackupRestore/index.html', title: { diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp index c37b4f8..458f1b6 100644 --- a/drm/common/IDrmManagerService.cpp +++ b/drm/common/IDrmManagerService.cpp @@ -37,7 +37,7 @@ using namespace android; -static void writeDecrptHandleToParcelData( +static void writeDecryptHandleToParcelData( const DecryptHandle* handle, Parcel* data) { data->writeInt32(handle->decryptId); data->writeString8(handle->mimeType); @@ -46,14 +46,14 @@ static void writeDecrptHandleToParcelData( int size = handle->copyControlVector.size(); data->writeInt32(size); - for(int i = 0; i < size; i++) { + for (int i = 0; i < size; i++) { data->writeInt32(handle->copyControlVector.keyAt(i)); data->writeInt32(handle->copyControlVector.valueAt(i)); } size = handle->extendedData.size(); data->writeInt32(size); - for(int i = 0; i < size; i++) { + for (int i = 0; i < size; i++) { data->writeString8(handle->extendedData.keyAt(i)); data->writeString8(handle->extendedData.valueAt(i)); } @@ -77,14 +77,14 @@ static void readDecryptHandleFromParcelData( handle->status = data.readInt32(); int size = data.readInt32(); - for (int i = 0; i < size; i ++) { + for (int i = 0; i < size; i++) { DrmCopyControl key = (DrmCopyControl)data.readInt32(); int value = data.readInt32(); handle->copyControlVector.add(key, value); } size = data.readInt32(); - for (int i = 0; i < size; i ++) { + for (int i = 0; i < size; i++) { String8 key = data.readString8(); String8 value = data.readString8(); handle->extendedData.add(key, value); @@ -416,7 +416,7 @@ status_t BpDrmManagerService::consumeRights( data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor()); data.writeInt32(uniqueId); - writeDecrptHandleToParcelData(decryptHandle, &data); + writeDecryptHandleToParcelData(decryptHandle, &data); data.writeInt32(action); data.writeInt32(static_cast< int>(reserve)); @@ -433,7 +433,7 @@ status_t BpDrmManagerService::setPlaybackStatus( data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor()); data.writeInt32(uniqueId); - writeDecrptHandleToParcelData(decryptHandle, &data); + writeDecryptHandleToParcelData(decryptHandle, &data); data.writeInt32(playbackStatus); data.writeInt64(position); @@ -646,7 +646,7 @@ status_t BpDrmManagerService::closeDecryptSession(int uniqueId, DecryptHandle* d data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor()); data.writeInt32(uniqueId); - writeDecrptHandleToParcelData(decryptHandle, &data); + writeDecryptHandleToParcelData(decryptHandle, &data); remote()->transact(CLOSE_DECRYPT_SESSION, data, &reply); @@ -662,7 +662,7 @@ status_t BpDrmManagerService::initializeDecryptUnit( data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor()); data.writeInt32(uniqueId); - writeDecrptHandleToParcelData(decryptHandle, &data); + writeDecryptHandleToParcelData(decryptHandle, &data); data.writeInt32(decryptUnitId); @@ -682,7 +682,7 @@ status_t BpDrmManagerService::decrypt( data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor()); data.writeInt32(uniqueId); - writeDecrptHandleToParcelData(decryptHandle, &data); + writeDecryptHandleToParcelData(decryptHandle, &data); data.writeInt32(decryptUnitId); data.writeInt32((*decBuffer)->length); @@ -715,7 +715,7 @@ status_t BpDrmManagerService::finalizeDecryptUnit( data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor()); data.writeInt32(uniqueId); - writeDecrptHandleToParcelData(decryptHandle, &data); + writeDecryptHandleToParcelData(decryptHandle, &data); data.writeInt32(decryptUnitId); @@ -733,7 +733,7 @@ ssize_t BpDrmManagerService::pread( data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor()); data.writeInt32(uniqueId); - writeDecrptHandleToParcelData(decryptHandle, &data); + writeDecryptHandleToParcelData(decryptHandle, &data); data.writeInt32(numBytes); data.writeInt64(offset); @@ -1244,7 +1244,7 @@ status_t BnDrmManagerService::onTransact( = openDecryptSession(uniqueId, fd, data.readInt64(), data.readInt64()); if (NULL != handle) { - writeDecrptHandleToParcelData(handle, reply); + writeDecryptHandleToParcelData(handle, reply); clearDecryptHandle(handle); delete handle; handle = NULL; } @@ -1262,7 +1262,7 @@ status_t BnDrmManagerService::onTransact( DecryptHandle* handle = openDecryptSession(uniqueId, uri.string()); if (NULL != handle) { - writeDecrptHandleToParcelData(handle, reply); + writeDecryptHandleToParcelData(handle, reply); clearDecryptHandle(handle); delete handle; handle = NULL; diff --git a/drm/java/android/drm/DrmInfoRequest.java b/drm/java/android/drm/DrmInfoRequest.java index 2222ae8..1429fa5 100755 --- a/drm/java/android/drm/DrmInfoRequest.java +++ b/drm/java/android/drm/DrmInfoRequest.java @@ -32,16 +32,16 @@ public class DrmInfoRequest { */ public static final int TYPE_REGISTRATION_INFO = 1; /** - * Acquires information for unregistering the DRM server. - */ + * Acquires information for unregistering the DRM server. + */ public static final int TYPE_UNREGISTRATION_INFO = 2; /** - * Acquires rights information. - */ + * Acquires rights information. + */ public static final int TYPE_RIGHTS_ACQUISITION_INFO = 3; /** - * Acquires the progress of the rights acquisition. - */ + * Acquires the progress of the rights acquisition. + */ public static final int TYPE_RIGHTS_ACQUISITION_PROGRESS_INFO = 4; /** diff --git a/drm/java/android/drm/DrmInfoStatus.java b/drm/java/android/drm/DrmInfoStatus.java index b04694b..5c12ae3 100755 --- a/drm/java/android/drm/DrmInfoStatus.java +++ b/drm/java/android/drm/DrmInfoStatus.java @@ -31,20 +31,20 @@ public class DrmInfoStatus { public static final int STATUS_ERROR = 2; /** - * The status of the communication. - */ + * The status of the communication. + */ public final int statusCode; /** - * The type of DRM information processed. - */ + * The type of DRM information processed. + */ public final int infoType; /** - * The MIME type of the content. - */ + * The MIME type of the content. + */ public final String mimeType; /** - * The processed data. - */ + * The processed data. + */ public final ProcessedData data; /** diff --git a/drm/libdrmframework/include/PlugInManager.h b/drm/libdrmframework/include/PlugInManager.h index 8029138..7bb143f 100644 --- a/drm/libdrmframework/include/PlugInManager.h +++ b/drm/libdrmframework/include/PlugInManager.h @@ -202,7 +202,7 @@ private: Vector<String8> getPlugInPathList(const String8& rsDirPath) { Vector<String8> fileList; DIR* pDir = opendir(rsDirPath.string()); - struct dirent* pEntry = new dirent(); + struct dirent* pEntry; while (NULL != pDir && NULL != (pEntry = readdir(pDir))) { if (!isPlugIn(pEntry)) { @@ -219,8 +219,6 @@ private: if (NULL != pDir) { closedir(pDir); } - delete pEntry; - pEntry = NULL; return fileList; } diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java index 0ffd201..6c7341f 100644 --- a/graphics/java/android/graphics/SurfaceTexture.java +++ b/graphics/java/android/graphics/SurfaceTexture.java @@ -66,11 +66,8 @@ public class SurfaceTexture { /** * This field is used by native code, do not access or modify. - * - * @hide */ - @SuppressWarnings({"UnusedDeclaration"}) - public int mSurfaceTexture; + private int mSurfaceTexture; /** * Callback interface for being notified that a new stream frame is available. diff --git a/include/utils/BlobCache.h b/include/utils/BlobCache.h index 8f76d72..dc45ff0 100644 --- a/include/utils/BlobCache.h +++ b/include/utils/BlobCache.h @@ -82,6 +82,9 @@ private: BlobCache(const BlobCache&); void operator=(const BlobCache&); + // A random function helper to get around MinGW not having nrand48() + long int blob_random(); + // clean evicts a randomly chosen set of entries from the cache such that // the total size of all remaining entries is less than mMaxTotalSize/2. void clean(); diff --git a/libs/rs/Android.mk b/libs/rs/Android.mk index 9fabf8d..d9cc6b6 100644 --- a/libs/rs/Android.mk +++ b/libs/rs/Android.mk @@ -119,6 +119,7 @@ LOCAL_SRC_FILES:= \ driver/rsdBcc.cpp \ driver/rsdCore.cpp \ driver/rsdFrameBuffer.cpp \ + driver/rsdFrameBufferObj.cpp \ driver/rsdGL.cpp \ driver/rsdMesh.cpp \ driver/rsdMeshObj.cpp \ diff --git a/libs/rs/driver/rsdAllocation.cpp b/libs/rs/driver/rsdAllocation.cpp index 8bfc185..01a0cf6 100644 --- a/libs/rs/driver/rsdAllocation.cpp +++ b/libs/rs/driver/rsdAllocation.cpp @@ -19,6 +19,7 @@ #include "rsdBcc.h" #include "rsdRuntime.h" #include "rsdAllocation.h" +#include "rsdFrameBufferObj.h" #include "rsAllocation.h" @@ -244,6 +245,9 @@ bool rsdAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) { if (alloc->mHal.state.usageFlags & ~RS_ALLOCATION_USAGE_SCRIPT) { drv->uploadDeferred = true; } + + drv->readBackFBO = NULL; + return true; } @@ -269,6 +273,10 @@ void rsdAllocationDestroy(const Context *rsc, Allocation *alloc) { free(drv->mallocPtr); drv->mallocPtr = NULL; } + if (drv->readBackFBO != NULL) { + delete drv->readBackFBO; + drv->readBackFBO = NULL; + } free(drv); alloc->mHal.drv = NULL; } @@ -292,13 +300,52 @@ void rsdAllocationResize(const Context *rsc, const Allocation *alloc, } } +static void rsdAllocationSyncFromFBO(const Context *rsc, const Allocation *alloc) { + if (!alloc->getIsScript()) { + return; // nothing to sync + } + + RsdHal *dc = (RsdHal *)rsc->mHal.drv; + RsdFrameBufferObj *lastFbo = dc->gl.currentFrameBuffer; + + DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; + if (!drv->textureID && !drv->renderTargetID) { + return; // nothing was rendered here yet, so nothing to sync + } + if (drv->readBackFBO == NULL) { + drv->readBackFBO = new RsdFrameBufferObj(); + drv->readBackFBO->setColorTarget(drv, 0); + drv->readBackFBO->setDimensions(alloc->getType()->getDimX(), + alloc->getType()->getDimY()); + } + + // Bind the framebuffer object so we can read back from it + drv->readBackFBO->setActive(rsc); + + // Do the readback + glReadPixels(0, 0, alloc->getType()->getDimX(), alloc->getType()->getDimY(), + drv->glFormat, drv->glType, alloc->getPtr()); + + // Revert framebuffer to its original + lastFbo->setActive(rsc); +} void rsdAllocationSyncAll(const Context *rsc, const Allocation *alloc, RsAllocationUsageType src) { DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; - if (!drv->uploadDeferred) { + if (src == RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) { + if(!alloc->getIsRenderTarget()) { + rsc->setError(RS_ERROR_FATAL_DRIVER, + "Attempting to sync allocation from render target, " + "for non-render target allocation"); + } else if (alloc->getType()->getElement()->getKind() != RS_KIND_PIXEL_RGBA) { + rsc->setError(RS_ERROR_FATAL_DRIVER, "Cannot only sync from RGBA" + "render target"); + } else { + rsdAllocationSyncFromFBO(rsc, alloc); + } return; } @@ -382,7 +429,40 @@ void rsdAllocationData1D_alloc(const android::renderscript::Context *rsc, const android::renderscript::Allocation *dstAlloc, uint32_t dstXoff, uint32_t dstLod, uint32_t count, const android::renderscript::Allocation *srcAlloc, - uint32_t srcXoff, uint32_t srcLod){ + uint32_t srcXoff, uint32_t srcLod) { +} + +uint8_t *getOffsetPtr(const android::renderscript::Allocation *alloc, + uint32_t xoff, uint32_t yoff, uint32_t lod, + RsAllocationCubemapFace face) { + uint8_t *ptr = static_cast<uint8_t *>(alloc->getPtr()); + ptr += alloc->getType()->getLODOffset(lod, xoff, yoff); + + if (face != 0) { + uint32_t totalSizeBytes = alloc->getType()->getSizeBytes(); + uint32_t faceOffset = totalSizeBytes / 6; + ptr += faceOffset * (uint32_t)face; + } + return ptr; +} + + +void rsdAllocationData2D_alloc_script(const android::renderscript::Context *rsc, + const android::renderscript::Allocation *dstAlloc, + uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod, + RsAllocationCubemapFace dstFace, uint32_t w, uint32_t h, + const android::renderscript::Allocation *srcAlloc, + uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod, + RsAllocationCubemapFace srcFace) { + uint32_t elementSize = dstAlloc->getType()->getElementSizeBytes(); + for (uint32_t i = 0; i < h; i ++) { + uint8_t *dstPtr = getOffsetPtr(dstAlloc, dstXoff, dstYoff + i, dstLod, dstFace); + uint8_t *srcPtr = getOffsetPtr(srcAlloc, srcXoff, srcYoff + i, srcLod, srcFace); + memcpy(dstPtr, srcPtr, w * elementSize); + + LOGE("COPIED dstXoff(%u), dstYoff(%u), dstLod(%u), dstFace(%u), w(%u), h(%u), srcXoff(%u), srcYoff(%u), srcLod(%u), srcFace(%u)", + dstXoff, dstYoff, dstLod, dstFace, w, h, srcXoff, srcYoff, srcLod, srcFace); + } } void rsdAllocationData2D_alloc(const android::renderscript::Context *rsc, @@ -392,6 +472,14 @@ void rsdAllocationData2D_alloc(const android::renderscript::Context *rsc, const android::renderscript::Allocation *srcAlloc, uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod, RsAllocationCubemapFace srcFace) { + if (!dstAlloc->getIsScript() && !srcAlloc->getIsScript()) { + rsc->setError(RS_ERROR_FATAL_DRIVER, "Non-script allocation copies not " + "yet implemented."); + return; + } + rsdAllocationData2D_alloc_script(rsc, dstAlloc, dstXoff, dstYoff, + dstLod, dstFace, w, h, srcAlloc, + srcXoff, srcYoff, srcLod, srcFace); } void rsdAllocationData3D_alloc(const android::renderscript::Context *rsc, diff --git a/libs/rs/driver/rsdAllocation.h b/libs/rs/driver/rsdAllocation.h index 7555c4a..4fc4419 100644 --- a/libs/rs/driver/rsdAllocation.h +++ b/libs/rs/driver/rsdAllocation.h @@ -23,6 +23,8 @@ #include <GLES/gl.h> #include <GLES2/gl2.h> +class RsdFrameBufferObj; + struct DrvAllocation { // Is this a legal structure to be used as a texture source. // Initially this will require 1D or 2D and color data @@ -42,8 +44,9 @@ struct DrvAllocation { GLenum glType; GLenum glFormat; - bool uploadDeferred; + + RsdFrameBufferObj * readBackFBO; }; GLenum rsdTypeToGLType(RsDataType t); diff --git a/libs/rs/driver/rsdFrameBuffer.cpp b/libs/rs/driver/rsdFrameBuffer.cpp index ce72b5d..8c1b12d 100644 --- a/libs/rs/driver/rsdFrameBuffer.cpp +++ b/libs/rs/driver/rsdFrameBuffer.cpp @@ -17,6 +17,7 @@ #include "rsdCore.h" #include "rsdFrameBuffer.h" +#include "rsdFrameBufferObj.h" #include "rsdAllocation.h" #include "rsContext.h" @@ -28,133 +29,70 @@ using namespace android; using namespace android::renderscript; -struct DrvFrameBuffer { - GLuint mFBOId; -}; - -void checkError(const Context *rsc) { - GLenum status; - status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - switch (status) { - case GL_FRAMEBUFFER_COMPLETE: - break; - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: - rsc->setError(RS_ERROR_BAD_VALUE, - "Unable to set up render Target: RFRAMEBUFFER_INCOMPLETE_ATTACHMENT"); - break; - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: - rsc->setError(RS_ERROR_BAD_VALUE, - "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"); - break; - case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: - rsc->setError(RS_ERROR_BAD_VALUE, - "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS"); - break; - case GL_FRAMEBUFFER_UNSUPPORTED: - rsc->setError(RS_ERROR_BAD_VALUE, - "Unable to set up render Target: GL_FRAMEBUFFER_UNSUPPORTED"); - break; - } -} - - void setDepthAttachment(const Context *rsc, const FBOCache *fb) { + RsdFrameBufferObj *fbo = (RsdFrameBufferObj*)fb->mHal.drv; + + DrvAllocation *depth = NULL; if (fb->mHal.state.depthTarget.get() != NULL) { - DrvAllocation *drv = (DrvAllocation *)fb->mHal.state.depthTarget->mHal.drv; - - if (drv->textureID) { - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, - GL_TEXTURE_2D, drv->textureID, 0); - } else { - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, - GL_RENDERBUFFER, drv->renderTargetID); + depth = (DrvAllocation *)fb->mHal.state.depthTarget->mHal.drv; + + if (depth->uploadDeferred) { + rsdAllocationSyncAll(rsc, fb->mHal.state.depthTarget.get(), + RS_ALLOCATION_USAGE_SCRIPT); } - } else { - // Reset last attachment - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0); } + fbo->setDepthTarget(depth); } void setColorAttachment(const Context *rsc, const FBOCache *fb) { + RsdFrameBufferObj *fbo = (RsdFrameBufferObj*)fb->mHal.drv; // Now attach color targets for (uint32_t i = 0; i < fb->mHal.state.colorTargetsCount; i ++) { - uint32_t texID = 0; + DrvAllocation *color = NULL; if (fb->mHal.state.colorTargets[i].get() != NULL) { - DrvAllocation *drv = (DrvAllocation *)fb->mHal.state.colorTargets[i]->mHal.drv; - - if (drv->textureID) { - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, - GL_TEXTURE_2D, drv->textureID, 0); - } else { - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, - GL_RENDERBUFFER, drv->renderTargetID); - } - } else { - // Reset last attachment - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, - GL_RENDERBUFFER, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, - GL_TEXTURE_2D, 0, 0); - } - } -} - -bool renderToFramebuffer(const FBOCache *fb) { - if (fb->mHal.state.depthTarget.get() != NULL) { - return false; - } + color = (DrvAllocation *)fb->mHal.state.colorTargets[i]->mHal.drv; - for (uint32_t i = 0; i < fb->mHal.state.colorTargetsCount; i ++) { - if (fb->mHal.state.colorTargets[i].get() != NULL) { - return false; + if (color->uploadDeferred) { + rsdAllocationSyncAll(rsc, fb->mHal.state.colorTargets[i].get(), + RS_ALLOCATION_USAGE_SCRIPT); + } } + fbo->setColorTarget(color, i); } - return true; } - bool rsdFrameBufferInit(const Context *rsc, const FBOCache *fb) { - DrvFrameBuffer *drv = (DrvFrameBuffer *)calloc(1, sizeof(DrvFrameBuffer)); - if (drv == NULL) { + RsdFrameBufferObj *fbo = new RsdFrameBufferObj(); + if (fbo == NULL) { return false; } - fb->mHal.drv = drv; - drv->mFBOId = 0; + fb->mHal.drv = fbo; + + RsdHal *dc = (RsdHal *)rsc->mHal.drv; + dc->gl.currentFrameBuffer = fbo; return true; } void rsdFrameBufferSetActive(const Context *rsc, const FBOCache *fb) { - DrvFrameBuffer *drv = (DrvFrameBuffer *)fb->mHal.drv; - - bool framebuffer = renderToFramebuffer(fb); - if (!framebuffer) { - if(drv->mFBOId == 0) { - glGenFramebuffers(1, &drv->mFBOId); - } - glBindFramebuffer(GL_FRAMEBUFFER, drv->mFBOId); - - setDepthAttachment(rsc, fb); - setColorAttachment(rsc, fb); - - glViewport(0, 0, fb->mHal.state.colorTargets[0]->getType()->getDimX(), - fb->mHal.state.colorTargets[0]->getType()->getDimY()); - - checkError(rsc); - } else { - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glViewport(0, 0, rsc->getWidth(), rsc->getHeight()); + setDepthAttachment(rsc, fb); + setColorAttachment(rsc, fb); + + RsdFrameBufferObj *fbo = (RsdFrameBufferObj *)fb->mHal.drv; + if (fb->mHal.state.colorTargets[0].get()) { + fbo->setDimensions(fb->mHal.state.colorTargets[0]->getType()->getDimX(), + fb->mHal.state.colorTargets[0]->getType()->getDimY()); + } else if (fb->mHal.state.depthTarget.get()) { + fbo->setDimensions(fb->mHal.state.depthTarget->getType()->getDimX(), + fb->mHal.state.depthTarget->getType()->getDimY()); } + + fbo->setActive(rsc); } void rsdFrameBufferDestroy(const Context *rsc, const FBOCache *fb) { - DrvFrameBuffer *drv = (DrvFrameBuffer *)fb->mHal.drv; - if(drv->mFBOId != 0) { - glDeleteFramebuffers(1, &drv->mFBOId); - } - - free(fb->mHal.drv); + RsdFrameBufferObj *fbo = (RsdFrameBufferObj *)fb->mHal.drv; + delete fbo; fb->mHal.drv = NULL; } diff --git a/libs/rs/driver/rsdFrameBufferObj.cpp b/libs/rs/driver/rsdFrameBufferObj.cpp new file mode 100644 index 0000000..145bf34 --- /dev/null +++ b/libs/rs/driver/rsdFrameBufferObj.cpp @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "rsdFrameBufferObj.h" +#include "rsdAllocation.h" + +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + +using namespace android; +using namespace android::renderscript; + +RsdFrameBufferObj::RsdFrameBufferObj() { + mFBOId = 0; + mWidth = 0; + mHeight = 0; + mColorTargetsCount = 1; + mColorTargets = new DrvAllocation*[mColorTargetsCount]; + for (uint32_t i = 0; i < mColorTargetsCount; i ++) { + mColorTargets[i] = 0; + } + mDepthTarget = NULL; + mDirty = true; +} + +RsdFrameBufferObj::~RsdFrameBufferObj() { + if(mFBOId != 0) { + glDeleteFramebuffers(1, &mFBOId); + } + delete [] mColorTargets; +} + +void RsdFrameBufferObj::checkError(const Context *rsc) { + GLenum status; + status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + switch (status) { + case GL_FRAMEBUFFER_COMPLETE: + break; + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: + rsc->setError(RS_ERROR_BAD_VALUE, + "Unable to set up render Target: RFRAMEBUFFER_INCOMPLETE_ATTACHMENT"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: + rsc->setError(RS_ERROR_BAD_VALUE, + "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: + rsc->setError(RS_ERROR_BAD_VALUE, + "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS"); + break; + case GL_FRAMEBUFFER_UNSUPPORTED: + rsc->setError(RS_ERROR_BAD_VALUE, + "Unable to set up render Target: GL_FRAMEBUFFER_UNSUPPORTED"); + break; + } +} + + +void RsdFrameBufferObj::setDepthAttachment() { + if (mDepthTarget != NULL) { + if (mDepthTarget->textureID) { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + GL_TEXTURE_2D, mDepthTarget->textureID, 0); + } else { + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + GL_RENDERBUFFER, mDepthTarget->renderTargetID); + } + } else { + // Reset last attachment + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0); + } +} + +void RsdFrameBufferObj::setColorAttachment() { + // Now attach color targets + for (uint32_t i = 0; i < mColorTargetsCount; i ++) { + if (mColorTargets[i] != NULL) { + if (mColorTargets[i]->textureID) { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, + GL_TEXTURE_2D, mColorTargets[i]->textureID, 0); + } else { + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, + GL_RENDERBUFFER, mColorTargets[i]->renderTargetID); + } + } else { + // Reset last attachment + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, + GL_RENDERBUFFER, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, + GL_TEXTURE_2D, 0, 0); + } + } +} + +bool RsdFrameBufferObj::renderToFramebuffer() { + if (mDepthTarget != NULL) { + return false; + } + + for (uint32_t i = 0; i < mColorTargetsCount; i ++) { + if (mColorTargets[i] != NULL) { + return false; + } + } + return true; +} + +void RsdFrameBufferObj::setActive(const Context *rsc) { + bool framebuffer = renderToFramebuffer(); + if (!framebuffer) { + if(mFBOId == 0) { + glGenFramebuffers(1, &mFBOId); + } + glBindFramebuffer(GL_FRAMEBUFFER, mFBOId); + + if (mDirty) { + setDepthAttachment(); + setColorAttachment(); + mDirty = false; + } + + glViewport(0, 0, mWidth, mHeight); + checkError(rsc); + } else { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glViewport(0, 0, rsc->getWidth(), rsc->getHeight()); + } +} diff --git a/libs/rs/driver/rsdFrameBufferObj.h b/libs/rs/driver/rsdFrameBufferObj.h new file mode 100644 index 0000000..c6e7deb --- /dev/null +++ b/libs/rs/driver/rsdFrameBufferObj.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _RSD_FRAMEBUFFER_OBJ_H_ +#define _RSD_FRAMEBUFFER_OBJ_H_ + +#include <rsContext.h> + +class DrvAllocation; + +class RsdFrameBufferObj { +public: + RsdFrameBufferObj(); + ~RsdFrameBufferObj(); + + void setActive(const android::renderscript::Context *rsc); + void setColorTarget(DrvAllocation *color, uint32_t index) { + mColorTargets[index] = color; + mDirty = true; + } + void setDepthTarget(DrvAllocation *depth) { + mDepthTarget = depth; + mDirty = true; + } + void setDimensions(uint32_t width, uint32_t height) { + mWidth = width; + mHeight = height; + } +protected: + uint32_t mFBOId; + DrvAllocation **mColorTargets; + uint32_t mColorTargetsCount; + DrvAllocation *mDepthTarget; + + uint32_t mWidth; + uint32_t mHeight; + + bool mDirty; + + bool renderToFramebuffer(); + void checkError(const android::renderscript::Context *rsc); + void setColorAttachment(); + void setDepthAttachment(); +}; + +#endif //_RSD_FRAMEBUFFER_STATE_H_ diff --git a/libs/rs/driver/rsdGL.cpp b/libs/rs/driver/rsdGL.cpp index a70589b..3ff03b4 100644 --- a/libs/rs/driver/rsdGL.cpp +++ b/libs/rs/driver/rsdGL.cpp @@ -39,6 +39,7 @@ #include "rsContext.h" #include "rsdShaderCache.h" #include "rsdVertexArray.h" +#include "rsdFrameBufferObj.h" using namespace android; using namespace android::renderscript; @@ -294,6 +295,7 @@ bool rsdGLInit(const Context *rsc) { dc->gl.shaderCache = new RsdShaderCache(); dc->gl.vertexArrayState = new RsdVertexArrayState(); dc->gl.vertexArrayState->init(dc->gl.gl.maxVertexAttribs); + dc->gl.currentFrameBuffer = NULL; LOGV("initGLThread end %p", rsc); return true; diff --git a/libs/rs/driver/rsdGL.h b/libs/rs/driver/rsdGL.h index 01c8438..0d5b7e7 100644 --- a/libs/rs/driver/rsdGL.h +++ b/libs/rs/driver/rsdGL.h @@ -22,6 +22,7 @@ class RsdShaderCache; class RsdVertexArrayState; +class RsdFrameBufferObj; typedef void (* InvokeFunc_t)(void); typedef void (*WorkerCallback_t)(void *usr, uint32_t idx); @@ -68,6 +69,7 @@ typedef struct RsdGLRec { uint32_t height; RsdShaderCache *shaderCache; RsdVertexArrayState *vertexArrayState; + RsdFrameBufferObj *currentFrameBuffer; } RsdGL; diff --git a/libs/rs/driver/rsdMeshObj.cpp b/libs/rs/driver/rsdMeshObj.cpp index c220ac1..4315c0d 100644 --- a/libs/rs/driver/rsdMeshObj.cpp +++ b/libs/rs/driver/rsdMeshObj.cpp @@ -138,7 +138,10 @@ void RsdMeshObj::renderPrimitiveRange(const Context *rsc, uint32_t primIndex, ui for (uint32_t ct=0; ct < mRSMesh->mHal.state.vertexBuffersCount; ct++) { const Allocation *alloc = mRSMesh->mHal.state.vertexBuffers[ct].get(); - rsdAllocationSyncAll(rsc, alloc, RS_ALLOCATION_USAGE_SCRIPT); + DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; + if (drv->uploadDeferred) { + rsdAllocationSyncAll(rsc, alloc, RS_ALLOCATION_USAGE_SCRIPT); + } } // update attributes with either buffer information or data ptr based on their current state @@ -163,7 +166,9 @@ void RsdMeshObj::renderPrimitiveRange(const Context *rsc, uint32_t primIndex, ui const Allocation *idxAlloc = prim->mIndexBuffer.get(); if (idxAlloc) { DrvAllocation *drvAlloc = (DrvAllocation *)idxAlloc->mHal.drv; - rsdAllocationSyncAll(rsc, idxAlloc, RS_ALLOCATION_USAGE_SCRIPT); + if (drvAlloc->uploadDeferred) { + rsdAllocationSyncAll(rsc, idxAlloc, RS_ALLOCATION_USAGE_SCRIPT); + } if (drvAlloc->bufferID) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, drvAlloc->bufferID); diff --git a/libs/rs/driver/rsdRuntimeStubs.cpp b/libs/rs/driver/rsdRuntimeStubs.cpp index bd8b3c3..25302aa 100644 --- a/libs/rs/driver/rsdRuntimeStubs.cpp +++ b/libs/rs/driver/rsdRuntimeStubs.cpp @@ -95,6 +95,8 @@ static void SC_AllocationCopy1DRange(Allocation *dstAlloc, Allocation *srcAlloc, uint32_t srcOff, uint32_t srcMip) { GET_TLS(); + rsrAllocationCopy1DRange(rsc, dstAlloc, dstOff, dstMip, count, + srcAlloc, srcOff, srcMip); } static void SC_AllocationCopy2DRange(Allocation *dstAlloc, @@ -105,6 +107,11 @@ static void SC_AllocationCopy2DRange(Allocation *dstAlloc, uint32_t srcXoff, uint32_t srcYoff, uint32_t srcMip, uint32_t srcFace) { GET_TLS(); + rsrAllocationCopy2DRange(rsc, dstAlloc, + dstXoff, dstYoff, dstMip, dstFace, + width, height, + srcAlloc, + srcXoff, srcYoff, srcMip, srcFace); } diff --git a/libs/rs/rsFBOCache.cpp b/libs/rs/rsFBOCache.cpp index 6960ef2..c5c64c2 100644 --- a/libs/rs/rsFBOCache.cpp +++ b/libs/rs/rsFBOCache.cpp @@ -80,16 +80,6 @@ void FBOCache::setup(Context *rsc) { return; } - if (mHal.state.depthTarget.get() != NULL) { - mHal.state.depthTarget->syncAll(rsc, RS_ALLOCATION_USAGE_SCRIPT); - } - - for (uint32_t i = 0; i < mHal.state.colorTargetsCount; i ++) { - if (mHal.state.colorTargets[i].get() != NULL) { - mHal.state.colorTargets[i]->syncAll(rsc, RS_ALLOCATION_USAGE_SCRIPT); - } - } - rsc->mHal.funcs.framebuffer.setActive(rsc, this); mDirty = false; diff --git a/libs/utils/BlobCache.cpp b/libs/utils/BlobCache.cpp index 1298fa7..590576a 100644 --- a/libs/utils/BlobCache.cpp +++ b/libs/utils/BlobCache.cpp @@ -31,9 +31,13 @@ BlobCache::BlobCache(size_t maxKeySize, size_t maxValueSize, size_t maxTotalSize mMaxTotalSize(maxTotalSize), mTotalSize(0) { nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); +#ifdef _WIN32 + srand(now); +#else mRandState[0] = (now >> 0) & 0xFFFF; mRandState[1] = (now >> 16) & 0xFFFF; mRandState[2] = (now >> 32) & 0xFFFF; +#endif LOGV("initializing random seed using %lld", now); } @@ -148,11 +152,19 @@ size_t BlobCache::get(const void* key, size_t keySize, void* value, return valueBlobSize; } +long int BlobCache::blob_random() { +#ifdef _WIN32 + return rand(); +#else + return nrand48(mRandState); +#endif +} + void BlobCache::clean() { // Remove a random cache entry until the total cache size gets below half // the maximum total cache size. while (mTotalSize > mMaxTotalSize / 2) { - size_t i = size_t(nrand48(mRandState) % (mCacheEntries.size())); + size_t i = size_t(blob_random() % (mCacheEntries.size())); const CacheEntry& entry(mCacheEntries[i]); mTotalSize -= entry.getKey()->getSize() + entry.getValue()->getSize(); mCacheEntries.removeAt(i); diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java index d6e1346..f3a91c5 100755 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java @@ -1,57 +1,54 @@ /* * Copyright (C) 2008 The Android Open Source Project * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. */ package com.android.mediaframeworktest; /** - * - * This class has the names of the all the activity name and variables - * in the instrumentation test. + * + * This class has the names of the all the activity name and variables in the + * instrumentation test. * */ public class MediaNames { - //A directory to hold all kinds of media files + // A directory to hold all kinds of media files public static final String MEDIA_SAMPLE_POOL = "/sdcard/media_api/samples/"; - //Audio files - public static final String MP3CBR = "/sdcard/media_api/music/MP3_256kbps_2ch.mp3"; - public static final String MP3VBR = "/sdcard/media_api/music/MP3_256kbps_2ch_VBR.mp3"; + // Audio files + public static final String MP3CBR = "/sdcard/media_api/music/MP3_48KHz_128kbps_s_1_17_CBR.mp3"; + public static final String MP3VBR = "/sdcard/media_api/music/MP3_48KHz_128kbps_s_1_17_VBR.mp3"; + public static final String MP3ABR = "/sdcard/media_api/music/MP3_48KHz_128kbps_s_1_17_ABR.mp3"; public static final String SHORTMP3 = "/sdcard/media_api/music/SHORTMP3.mp3"; public static final String MIDI = "/sdcard/media_api/music/ants.mid"; - public static final String WMA9 = "/sdcard/media_api/music/WMA9.wma"; - public static final String WMA10 = "/sdcard/media_api/music/WMA10.wma"; public static final String WAV = "/sdcard/media_api/music/rings_2ch.wav"; public static final String AMR = "/sdcard/media_api/music/test_amr_ietf.amr"; - public static final String OGG = "/sdcard/media_api/music/Revelation.ogg"; public static final String SINE_200_1000 = "/sdcard/media_api/music/sine_200+1000Hz_44K_mo.wav"; - + // public static final String OGG = + // "/sdcard/media_api/music/Revelation.ogg"; + public static final int MP3CBR_LENGTH = 71000; public static final int MP3VBR_LENGTH = 71000; public static final int SHORTMP3_LENGTH = 286; public static final int MIDI_LENGTH = 17000; - public static final int WMA9_LENGTH = 126559; - public static final int WMA10_LENGTH = 126559; public static final int AMR_LENGTH = 37000; - public static final int OGG_LENGTH = 4000; public static final int SEEK_TIME = 10000; - + public static final long PAUSE_WAIT_TIME = 3000; public static final long WAIT_TIME = 2000; public static final long WAIT_SNAPSHOT_TIME = 5000; - //local video + // local video public static final String VIDEO_MP4 = "/sdcard/media_api/video/MPEG4_320_AAC_64.mp4"; public static final String VIDEO_SHORT_3GP = "/sdcard/media_api/video/short.3gp"; public static final String VIDEO_LARGE_SIZE_3GP = "/sdcard/media_api/video/border_large.3gp"; @@ -59,185 +56,105 @@ public class MediaNames { public static final String VIDEO_H263_AMR = "/sdcard/media_api/video/H263_56_AMRNB_6.3gp"; public static final String VIDEO_H264_AAC = "/sdcard/media_api/video/H264_320_AAC_64.3gp"; public static final String VIDEO_H264_AMR = "/sdcard/media_api/video/H264_320_AMRNB_6.3gp"; - public static final String VIDEO_WMV = "/sdcard/media_api/video/bugs.wmv"; public static final String VIDEO_HIGHRES_H263 = "/sdcard/media_api/video/H263_500_AMRNB_12.3gp"; public static final String VIDEO_HIGHRES_MP4 = "/sdcard/media_api/video/H264_500_AAC_128.3gp"; - - //Media Recorder + public static final String VIDEO_WEBM = "/sdcard/media_api/video/big-buck-bunny_trailer.webm"; + + // Media Recorder public static final String RECORDER_OUTPUT = "/sdcard/media_api/recorderOutput.amr"; - //video thumbnail + // video thumbnail public static final String THUMBNAIL_OUTPUT = "/sdcard/media_api/videoThumbnail.png"; public static final String GOLDEN_THUMBNAIL_OUTPUT = "/sdcard/media_api/goldenThumbnail.png"; - public static final String GOLDEN_THUMBNAIL_OUTPUT_2 = "/sdcard/media_api/goldenThumbnail2.png"; - - //Metadata Utility - public static final String[] THUMBNAIL_CAPTURE_TEST_FILES = { - "/sdcard/media_api/metadata/test.mp4", - "/sdcard/media_api/metadata/test1.3gp", - "/sdcard/media_api/metadata/test2.3gp", - "/sdcard/media_api/metadata/test3.3gp", - "/sdcard/media_api/metadata/test4.3gp", - "/sdcard/media_api/metadata/test5.3gp", - "/sdcard/media_api/metadata/test6.3gp", - "/sdcard/media_api/metadata/test7.3gp", - "/sdcard/media_api/metadata/test8.3gp", - "/sdcard/media_api/metadata/test9.3gp", - "/sdcard/media_api/metadata/test10.3gp", - "/sdcard/media_api/metadata/test11.3gp", - "/sdcard/media_api/metadata/test12.3gp", - "/sdcard/media_api/metadata/test13.3gp", - "/sdcard/media_api/metadata/test14.3gp", - "/sdcard/media_api/metadata/test15.3gp", - "/sdcard/media_api/metadata/test16.3gp", - "/sdcard/media_api/metadata/test17.3gp", - "/sdcard/media_api/metadata/test18.3gp", - "/sdcard/media_api/metadata/test19.3gp", - "/sdcard/media_api/metadata/test20.3gp", - "/sdcard/media_api/metadata/test21.3gp", - "/sdcard/media_api/metadata/test22.3gp", - "/sdcard/media_api/metadata/test23.3gp", - "/sdcard/media_api/metadata/test24.3gp", - "/sdcard/media_api/metadata/test25.3gp", - "/sdcard/media_api/metadata/test26.3gp", - "/sdcard/media_api/metadata/test27.3gp", - "/sdcard/media_api/metadata/test28.3gp", - "/sdcard/media_api/metadata/test29.3gp", - "/sdcard/media_api/metadata/test30.3gp", - "/sdcard/media_api/metadata/test31.3gp", - "/sdcard/media_api/metadata/test32.3gp", - "/sdcard/media_api/metadata/test33.3gp", - "/sdcard/media_api/metadata/test35.mp4", - "/sdcard/media_api/metadata/test36.m4v", - "/sdcard/media_api/metadata/test34.wmv", - "/sdcard/media_api/metadata/test_metadata.mp4", - }; - - public static final String[] METADATA_RETRIEVAL_TEST_FILES = { - // Raw AAC is not supported - // "/sdcard/media_api/test_raw.aac", - // "/sdcard/media_api/test_adts.aac", - // "/sdcard/media_api/test_adif.aac", - "/sdcard/media_api/metadata/test_metadata.mp4", - "/sdcard/media_api/metadata/WMA10.wma", - "/sdcard/media_api/metadata/Leadsol_out.wav", - "/sdcard/media_api/metadata/test_aac.mp4", - "/sdcard/media_api/metadata/test_amr.mp4", - "/sdcard/media_api/metadata/test_avc_amr.mp4", - "/sdcard/media_api/metadata/test_metadata.mp4", - "/sdcard/media_api/metadata/test_vbr.mp3", - "/sdcard/media_api/metadata/test_cbr.mp3", - "/sdcard/media_api/metadata/metadata_test1.mp3", - "/sdcard/media_api/metadata/test33.3gp", - "/sdcard/media_api/metadata/test35.mp4", - "/sdcard/media_api/metadata/test36.m4v", - "/sdcard/media_api/metadata/test_m4v_amr.mp4", - "/sdcard/media_api/metadata/test_h263_amr.mp4", - "/sdcard/media_api/metadata/test34.wmv", - }; - - public static final String[] ALBUMART_TEST_FILES = { - "/sdcard/media_api/album_photo/test_22_16_mp3.mp3", - "/sdcard/media_api/album_photo/PD_256kbps_48khz_mono_CBR_MCA.mp3", - "/sdcard/media_api/album_photo/PD_256kbps_44.1khz_mono_CBR_DPA.mp3", - "/sdcard/media_api/album_photo/PD_192kbps_32khz_mono_CBR_DPA.mp3", - "/sdcard/media_api/album_photo/NIN_256kbps_48khz_mono_CBR_MCA.mp3", - "/sdcard/media_api/album_photo/NIN_256kbps_44.1khz_mono_CBR_MCA.mp3", - "/sdcard/media_api/album_photo/NIN_112kbps(96kbps)_48khz_stereo_VBR_MCA.mp3", - "/sdcard/media_api/album_photo/NIN_112kbps(96kbps)_44.1khz_stereo_VBR_MCA.mp3", - "/sdcard/media_api/album_photo/lightGreen1.mp3", - "/sdcard/media_api/album_photo/babyBlue2 1.mp3", - "/sdcard/media_api/album_photo/2-01 01 NIN_56kbps(64kbps)_32khz_stereo_VBR_MCA.mp3", - "/sdcard/media_api/album_photo/02_NIN_112kbps(80kbps)_32khz_stereo_VBR_MCA.mp3", - "/sdcard/media_api/album_photo/No_Woman_No_Cry_128K.wma", - "/sdcard/media_api/album_photo/Beethoven_2.wma", - }; - - //TEST_PATH_1: is a video and contains metadata for key "num-tracks" - // TEST_PATH_2: any valid media file. - // TEST_PATH_3: invalid media file - public static final String TEST_PATH_1 = "/sdcard/media_api/metadata/test.mp4"; - public static final String TEST_PATH_3 = "/sdcard/media_api/data.txt"; - public static final String TEST_PATH_4 = "somenonexistingpathname"; - public static final String TEST_PATH_5 = "mem://012345"; - - //Meta data expected result - //The expected tag result in the following order - //cd_track_number, album, artist, author, composer, date, genre - //title, years, duration - public static final String META_DATA_MP3 [][] = { - {"/sdcard/media_api/metaDataTestMedias/MP3/ID3V1_ID3V2.mp3", "1/10", "ID3V2.3 Album", "ID3V2.3 Artist", - "ID3V2.3 Lyricist", "ID3V2.3 Composer", null, "Blues", - "ID3V2.3 Title", "1234", "295", "1", null}, - {"/sdcard/media_api/metaDataTestMedias/MP3/ID3V2.mp3", "1/10", "ID3V2.3 Album", "ID3V2.3 Artist", - "ID3V2.3 Lyricist", "ID3V2.3 Composer", null, "Blues", - "ID3V2.3 Title", "1234", "287", "1", null}, - {"/sdcard/media_api/metaDataTestMedias/MP3/ID3V1.mp3", "1", "test ID3V1 Album", "test ID3V1 Artist", - null, null, null, "255", "test ID3V1 Title", "1234", "231332", "1", null}, - {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V1.mp3" , null, null, null, - null, null, null, null, null, null, "231330", "1", null}, - //The corrupted TALB field in id3v2 would not switch to id3v1 tag automatically - {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TALB.mp3", "01", null, "ID3V2.3 Artist", - "ID3V2.3 Lyricist", "ID3V2.3 Composer", null, - "Blues", "ID3V2.3 Title", "1234", "295", "1", null}, - {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TCOM.mp3", "01", "ID3V2.3 Album", - "ID3V2.3 Artist", "ID3V2.3 Lyricist", null, null, - "Blues", "ID3V2.3 Title", "1234", "295", "1", null}, - {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TCOM_2.mp3", "01", "ID3V2.3 Album", - "ID3V2.3 Artist", null, null, null, "Blues", "ID3V2.3 Title", "1234", "295", "1", null}, - {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TRCK.mp3", "dd", "ID3V2.3 Album", - "ID3V2.3 Artist", "ID3V2.3 Lyricist", "ID3V2.3 Composer", null, - "Blues", "ID3V2.3 Title", "1234", "295", "1", null}, - {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TRCK_2.mp3", "01", "ID3V2.3 Album", - "ID3V2.3 Artist", null, null, null, null, "ID3V2.3 Title", null, "295", "1", null}, - {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TYER.mp3", "01", "ID3V2.3 Album", - "ID3V2.3 Artist", null, null, null, null, "ID3V2.3 Title", "9999", "295", "1", null}, - {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TYER_2.mp3", "01", "ID3V2.3 Album", - "ID3V2.3 Artist", "ID3V2.3 Lyricist", "ID3V2.3 Composer", null, - "Blues", "ID3V2.3 Title", null, "295", "1", null}, - {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TIT.mp3", null, null, null, - null, null, null, null, null, null, "295", "1", null} - }; - - //output recorded video - - public static final String RECORDED_HVGA_H263 = "/sdcard/HVGA_H263.3gp"; - public static final String RECORDED_QVGA_H263 = "/sdcard/QVGA_H263.3gp"; - public static final String RECORDED_SQVGA_H263 = "/sdcard/SQVGA_H263.3gp"; - public static final String RECORDED_CIF_H263 = "/sdcard/CIF_H263.3gp"; - public static final String RECORDED_QCIF_H263 = "/sdcard/QCIF_H263.3gp"; - public static final String RECORDED_PORTRAIT_H263 = "/sdcard/QCIF_mp4.3gp"; - - public static final String RECORDED_HVGA_MP4 = "/sdcard/HVGA_mp4.mp4"; - public static final String RECORDED_QVGA_MP4 = "/sdcard/QVGA_mp4.mp4"; - public static final String RECORDED_SQVGA_MP4 = "/sdcard/SQVGA_mp4.mp4"; - public static final String RECORDED_CIF_MP4 = "/sdcard/CIF_mp4.mp4"; - public static final String RECORDED_QCIF_MP4 = "/sdcard/QCIF_mp4.mp4"; - - public static final String RECORDED_VIDEO_3GP = "/sdcard/temp.3gp"; - - public static final String INVALD_VIDEO_PATH = "/sdcard/media_api/filepathdoesnotexist" + - "/filepathdoesnotexist/temp.3gp"; - - - public static final long RECORDED_TIME = 5000; - public static final long VALID_VIDEO_DURATION = 2000; - - //Streaming test files - public static final byte [] STREAM_SERVER = new byte[] {(byte)75,(byte)17,(byte)48,(byte)204}; - public static final String STREAM_H264_480_360_1411k = - "http://75.17.48.204:10088/yslau/stress_media/h264_regular.mp4"; - public static final String STREAM_WMV = - "http://75.17.48.204:10088/yslau/stress_media/bugs.wmv"; - public static final String STREAM_H263_176x144_325k = - "http://75.17.48.204:10088/yslau/stress_media/h263_regular.3gp"; - public static final String STREAM_H264_352x288_1536k = - "http://75.17.48.204:10088/yslau/stress_media/h264_highBitRate.mp4"; - public static final String STREAM_MP3= - "http://75.17.48.204:10088/yslau/stress_media/mp3_regular.mp3"; - public static final String STREAM_MPEG4_QVGA_128k = - "http://75.17.48.204:10088/yslau/stress_media/mpeg4_qvga_24fps.3gp"; - public static final int STREAM_H264_480_360_1411k_DURATION = 46000; - public static final int VIDEO_H263_AAC_DURATION = 501000; - public static final int VIDEO_H263_AMR_DURATION = 502000; + + /* + * Metadata Utility Test media files which contain meta data. + */ + public static final String[] THUMBNAIL_METADATA_TEST_FILES = { + "/sdcard/media_api/video/H263_500_AMRNB_12.3gp", + "/sdcard/media_api/video/H263_56_AAC_24.3gp", + "/sdcard/media_api/video/H263_56_AMRNB_6.3gp", + "/sdcard/media_api/video/H264_320_AAC_64.3gp", + "/sdcard/media_api/video/H264_320_AMRNB_6.3gp", + "/sdcard/media_api/video/H264_500_AAC_128.3gp", + "/sdcard/media_api/video/H264_HVGA_500_NO_AUDIO.3gp", + "/sdcard/media_api/video/H264_QVGA_500_NO_AUDIO.3gp", + "/sdcard/media_api/video/MPEG4_320_AAC_64.mp4", + "/sdcard/media_api/video/border_large.3gp", + "/sdcard/media_api/videoeditor/H264_BP_800x480_15fps_512kbps_AACLC_24KHz_38Kbps_s_1_17.mp4", + "/sdcard/media_api/videoeditor/H264_MP_960x720_25fps_800kbps_AACLC_48Khz_192Kbps_s_1_17.mp4", + "/sdcard/media_api/videoeditor/MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4", + "/sdcard/media_api/videoeditor/MPEG4_SP_176x144_12fps_92kbps_AMRNB_8KHz_12.2kbps_m_0_27.3gp", + "/sdcard/media_api/videoeditor/MPEG4_SP_720x480_30fps_280kbps_AACLC_48kHz_161kbps_s_0_26.mp4" + }; + + public static final String[] ALBUMART_TEST_FILES = { + "/sdcard/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V1_ID3V2.mp3", + "/sdcard/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V2.mp3", + "/sdcard/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V1.mp3", + }; + + // TEST_PATH_1: is a video and contains metadata for key "num-tracks" + // TEST_PATH_2: any valid media file. + // TEST_PATH_3: invalid media file + public static final String TEST_PATH_1 = "/sdcard/media_api/video/MPEG4_320_AAC_64.mp4"; + public static final String TEST_PATH_3 = "/sdcard/media_api/data.txt"; + public static final String TEST_PATH_4 = "somenonexistingpathname"; + public static final String TEST_PATH_5 = "mem://012345"; + + // Meta data expected result + // The expected tag result in the following order + // cd_track_number, album, artist, author, composer, date, genre + // title, years, duration + public static final String META_DATA_MP3[][] = { + {"/sdcard/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V1_ID3V2.mp3", "2/34", + "Test ID3V2 Album", "Test ID3V2 Artist", null, "Test ID3V2 Composer", + null, "(1)Classic Rock", "Test ID3V2 Title ", null, "77640", "1", null}, + {"/sdcard/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V2.mp3", "1/10", + "Test ID3V2 Album", "Test ID3V2 Artist", null, "Test ID3V2 Composer", + null, "(74)Acid Jazz", "Test ID3V2 Tag", null, "77640", "1", null}, + {"/sdcard/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V1.mp3", "2", + "Test ID3V1 Album", "Test ID3V1 Artist", null, null, null, "(15)", + "Test ID3V1 Title", "2011", "77640", "1", null} + }; + + // output recorded video + public static final String RECORDED_HVGA_H263 = "/sdcard/HVGA_H263.3gp"; + public static final String RECORDED_QVGA_H263 = "/sdcard/QVGA_H263.3gp"; + public static final String RECORDED_SQVGA_H263 = "/sdcard/SQVGA_H263.3gp"; + public static final String RECORDED_CIF_H263 = "/sdcard/CIF_H263.3gp"; + public static final String RECORDED_QCIF_H263 = "/sdcard/QCIF_H263.3gp"; + public static final String RECORDED_PORTRAIT_H263 = "/sdcard/QCIF_mp4.3gp"; + + public static final String RECORDED_HVGA_MP4 = "/sdcard/HVGA_mp4.mp4"; + public static final String RECORDED_QVGA_MP4 = "/sdcard/QVGA_mp4.mp4"; + public static final String RECORDED_SQVGA_MP4 = "/sdcard/SQVGA_mp4.mp4"; + public static final String RECORDED_CIF_MP4 = "/sdcard/CIF_mp4.mp4"; + public static final String RECORDED_QCIF_MP4 = "/sdcard/QCIF_mp4.mp4"; + + public static final String RECORDED_VIDEO_3GP = "/sdcard/temp.3gp"; + + public static final String INVALD_VIDEO_PATH = + "/sdcard/media_api/filepathdoesnotexist" + "/filepathdoesnotexist/temp.3gp"; + + public static final long RECORDED_TIME = 5000; + public static final long VALID_VIDEO_DURATION = 2000; + + // Streaming test files + public static final byte[] STREAM_SERVER = + new byte[] {(byte) 75, (byte) 17, (byte) 48, (byte) 204}; + public static final String STREAM_H264_480_360_1411k = + "http://75.17.48.204:10088/yslau/stress_media/h264_regular.mp4"; + public static final String STREAM_WMV = "http://75.17.48.204:10088/yslau/stress_media/bugs.wmv"; + public static final String STREAM_H263_176x144_325k = + "http://75.17.48.204:10088/yslau/stress_media/h263_regular.3gp"; + public static final String STREAM_H264_352x288_1536k = + "http://75.17.48.204:10088/yslau/stress_media/h264_highBitRate.mp4"; + public static final String STREAM_MP3 = + "http://75.17.48.204:10088/yslau/stress_media/mp3_regular.mp3"; + public static final String STREAM_MPEG4_QVGA_128k = + "http://75.17.48.204:10088/yslau/stress_media/mpeg4_qvga_24fps.3gp"; + public static final int STREAM_H264_480_360_1411k_DURATION = 46000; + public static final int VIDEO_H263_AAC_DURATION = 501000; + public static final int VIDEO_H263_AMR_DURATION = 502000; } diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java index 00e0a52..380de9c 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java @@ -41,10 +41,7 @@ public class MediaMetadataTest extends AndroidTestCase { } public static enum MP3_TEST_FILE{ - ID3V1V2, ID3V2, ID3V1, - CORRUPTED_ID3V1, CORRUPTED_ID3V2_TALB, CORRUPTED_ID3V2_TCOM, - CORRUPTED_ID3V2_TCOM_2, CORRUPTED_ID3V2_TRCK, CORRUPTED_D3V2_TRCK_2, - CORRUPTED_ID3V2_TYER, CORRUPTED_ID3V2_TYER_2, CORRUPTED_ID3V2_TIT + ID3V1V2, ID3V2, ID3V1 } public static METADATA_EXPECTEDRESULT meta; @@ -64,53 +61,7 @@ public class MediaMetadataTest extends AndroidTestCase { public static void testID3V1Metadata() throws Exception { validateMetatData(mp3_test_file.ID3V1.ordinal(), MediaNames.META_DATA_MP3); } - - @MediumTest - public static void testCorruptedID3V1Metadata() throws Exception { - validateMetatData(mp3_test_file.CORRUPTED_ID3V1.ordinal(), MediaNames.META_DATA_MP3); - } - @MediumTest - public static void testCorrupted_ID3V2_TALBMetadata() throws Exception { - validateMetatData(mp3_test_file.CORRUPTED_ID3V2_TALB.ordinal(), MediaNames.META_DATA_MP3); - } - - @MediumTest - public static void testCorrupted_ID3V2_TCOMMetadata() throws Exception { - validateMetatData(mp3_test_file.CORRUPTED_ID3V2_TCOM.ordinal(), MediaNames.META_DATA_MP3); - } - - @MediumTest - public static void testCorrupted_ID3V2_TCOMM2etadata() throws Exception { - validateMetatData(mp3_test_file.CORRUPTED_ID3V2_TCOM_2.ordinal(), MediaNames.META_DATA_MP3); - } - - @MediumTest - public static void testCorrupted_ID3V2_TRCKMetadata() throws Exception { - validateMetatData(mp3_test_file.CORRUPTED_ID3V2_TRCK.ordinal(), MediaNames.META_DATA_MP3); - } - - @MediumTest - public static void testCorrupted_ID3V2_TRCK2Metadata() throws Exception { - validateMetatData(mp3_test_file.CORRUPTED_D3V2_TRCK_2.ordinal(), MediaNames.META_DATA_MP3); - } - - @MediumTest - public static void testCorrupted_ID3V2_TYERMetadata() throws Exception { - validateMetatData(mp3_test_file.CORRUPTED_ID3V2_TYER.ordinal(), MediaNames.META_DATA_MP3); - } - - @MediumTest - public static void testCorrupted_ID3V2_TYER2Metadata() throws Exception { - validateMetatData(mp3_test_file.CORRUPTED_ID3V2_TYER_2.ordinal(), MediaNames.META_DATA_MP3); - } - - @MediumTest - public static void testCorrupted_ID3V2_TITMetadata() throws Exception { - validateMetatData(mp3_test_file.CORRUPTED_ID3V2_TIT.ordinal(), MediaNames.META_DATA_MP3); - } - - private static void validateMetatData(int fileIndex, String meta_data_file[][]) { Log.v(TAG, "filePath = "+ meta_data_file[fileIndex][0]); if ((meta_data_file[fileIndex][0].endsWith("wma") && !MediaProfileReader.getWMAEnable()) || diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java index 3a9564d..57d5368 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java @@ -84,15 +84,6 @@ public class MediaPlayerApiTest extends ActivityInstrumentationTestCase<MediaFra duratoinWithinTolerence = verifyDuration(duration, MediaNames.MIDI_LENGTH); assertTrue("MIDI getDuration", duratoinWithinTolerence); } - - @MediumTest - public void testWMA9GetDuration() throws Exception { - if (isWMAEnable) { - int duration = CodecTest.getDuration(MediaNames.WMA9); - duratoinWithinTolerence = verifyDuration(duration, MediaNames.WMA9_LENGTH); - assertTrue("WMA9 getDuration", duratoinWithinTolerence); - } - } @MediumTest public void testAMRGetDuration() throws Exception { @@ -127,15 +118,7 @@ public class MediaPlayerApiTest extends ActivityInstrumentationTestCase<MediaFra boolean currentPosition = CodecTest.getCurrentPosition(MediaNames.MIDI); assertTrue("MIDI GetCurrentPosition", currentPosition); } - - @LargeTest - public void testWMA9GetCurrentPosition() throws Exception { - if (isWMAEnable) { - boolean currentPosition = CodecTest.getCurrentPosition(MediaNames.WMA9); - assertTrue("WMA9 GetCurrentPosition", currentPosition); - } - } - + @LargeTest public void testAMRGetCurrentPosition() throws Exception { boolean currentPosition = CodecTest.getCurrentPosition(MediaNames.AMR); @@ -166,15 +149,7 @@ public class MediaPlayerApiTest extends ActivityInstrumentationTestCase<MediaFra boolean isPaused = CodecTest.pause(MediaNames.MIDI); assertTrue("MIDI Pause", isPaused); } - - @LargeTest - public void testWMA9Pause() throws Exception { - if (isWMAEnable) { - boolean isPaused = CodecTest.pause(MediaNames.WMA9); - assertTrue("WMA9 Pause", isPaused); - } - } - + @LargeTest public void testAMRPause() throws Exception { boolean isPaused = CodecTest.pause(MediaNames.AMR); @@ -239,15 +214,7 @@ public class MediaPlayerApiTest extends ActivityInstrumentationTestCase<MediaFra boolean isLoop = CodecTest.setLooping(MediaNames.MIDI); assertTrue("MIDI setLooping", isLoop); } - - @LargeTest - public void testWMA9SetLooping() throws Exception { - if (isWMAEnable) { - boolean isLoop = CodecTest.setLooping(MediaNames.WMA9); - assertTrue("WMA9 setLooping", isLoop); - } - } - + @LargeTest public void testAMRSetLooping() throws Exception { boolean isLoop = CodecTest.setLooping(MediaNames.AMR); @@ -279,15 +246,7 @@ public class MediaPlayerApiTest extends ActivityInstrumentationTestCase<MediaFra boolean isLoop = CodecTest.seekTo(MediaNames.MIDI); assertTrue("MIDI seekTo", isLoop); } - - @LargeTest - public void testWMA9SeekTo() throws Exception { - if (isWMAEnable) { - boolean isLoop = CodecTest.seekTo(MediaNames.WMA9); - assertTrue("WMA9 seekTo", isLoop); - } - } - + @LargeTest public void testAMRSeekTo() throws Exception { boolean isLoop = CodecTest.seekTo(MediaNames.AMR); @@ -320,15 +279,6 @@ public class MediaPlayerApiTest extends ActivityInstrumentationTestCase<MediaFra boolean isEnd = CodecTest.seekToEnd(MediaNames.MIDI); assertTrue("MIDI seekToEnd", isEnd); } - - @Suppress - @LargeTest - public void testWMA9SeekToEnd() throws Exception { - if (isWMAEnable) { - boolean isEnd = CodecTest.seekToEnd(MediaNames.WMA9); - assertTrue("WMA9 seekToEnd", isEnd); - } - } @LargeTest public void testAMRSeekToEnd() throws Exception { @@ -393,17 +343,13 @@ public class MediaPlayerApiTest extends ActivityInstrumentationTestCase<MediaFra boolean isSeek = CodecTest.videoSeekTo(MediaNames.VIDEO_H264_AMR); assertTrue("H264AMR SeekTo", isSeek); } - + @LargeTest - public void testVideoWMVSeekTo() throws Exception { - Log.v(TAG, "wmv not enable"); - if (isWMVEnable) { - Log.v(TAG, "wmv enable"); - boolean isSeek = CodecTest.videoSeekTo(MediaNames.VIDEO_WMV); - assertTrue("WMV SeekTo", isSeek); - } + public void testVideoWebmSeekTo() throws Exception { + boolean isSeek = CodecTest.videoSeekTo(MediaNames.VIDEO_WEBM); + assertTrue("WEBM SeekTo", isSeek); } - + @LargeTest public void testSoundRecord() throws Exception { boolean isRecordered = CodecTest.mediaRecorderRecord(MediaNames.RECORDER_OUTPUT); @@ -412,7 +358,7 @@ public class MediaPlayerApiTest extends ActivityInstrumentationTestCase<MediaFra @LargeTest public void testGetThumbnail() throws Exception { - boolean getThumbnail = CodecTest.getThumbnail(MediaNames.VIDEO_H264_AAC, MediaNames.GOLDEN_THUMBNAIL_OUTPUT_2); + boolean getThumbnail = CodecTest.getThumbnail(MediaNames.VIDEO_H264_AAC, MediaNames.GOLDEN_THUMBNAIL_OUTPUT); assertTrue("Get Thumbnail", getThumbnail); } diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java index 3b5b9a3..b396223 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java @@ -356,26 +356,6 @@ public class MediaPlayerPerformance extends ActivityInstrumentationTestCase2<Med assertTrue("H264 playback memory test", memoryResult); } - // Test case 3: Capture the memory usage after each 20 WMV playback - @LargeTest - public void testWMVVideoPlaybackMemoryUsage() throws Exception { - boolean memoryResult = false; - if (MediaProfileReader.getWMVEnable()){ - mStartPid = getMediaserverPid(); - File wmvMemoryOut = new File(MEDIA_MEMORY_OUTPUT); - Writer output = new BufferedWriter(new FileWriter(wmvMemoryOut, true)); - output.write("WMV video playback only\n"); - for (int i = 0; i < NUM_STRESS_LOOP; i++) { - mediaStressPlayback(MediaNames.VIDEO_WMV); - getMemoryWriteToLog(output, i); - } - output.write("\n"); - memoryResult = validateMemoryResult(mStartPid, mStartMemory, output, DECODER_LIMIT); - output.close(); - assertTrue("wmv playback memory test", memoryResult); - } - } - // Test case 4: Capture the memory usage after every 20 video only recorded @LargeTest public void testH263RecordVideoOnlyMemoryUsage() throws Exception { diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java index a66db05..8eb75f3 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java @@ -76,29 +76,29 @@ public class MediaMetadataRetrieverTest extends AndroidTestCase { boolean hasFailed = false; Log.v(TAG, "Thumbnail processing starts"); long startedAt = System.currentTimeMillis(); - for(int i = 0, n = MediaNames.THUMBNAIL_CAPTURE_TEST_FILES.length; i < n; ++i) { + for(int i = 0, n = MediaNames.THUMBNAIL_METADATA_TEST_FILES.length; i < n; ++i) { try { - Log.v(TAG, "File " + i + ": " + MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i]); - if ((MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i].endsWith(".wma") && !supportWMA) || - (MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i].endsWith(".wmv") && !supportWMV) + Log.v(TAG, "File " + i + ": " + MediaNames.THUMBNAIL_METADATA_TEST_FILES[i]); + if ((MediaNames.THUMBNAIL_METADATA_TEST_FILES[i].endsWith(".wma") && !supportWMA) || + (MediaNames.THUMBNAIL_METADATA_TEST_FILES[i].endsWith(".wmv") && !supportWMV) ) { Log.v(TAG, "windows media is not supported and thus we will skip the test for this file"); continue; } - retriever.setDataSource(MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i]); + retriever.setDataSource(MediaNames.THUMBNAIL_METADATA_TEST_FILES[i]); Bitmap bitmap = retriever.getFrameAtTime(-1); assertTrue(bitmap != null); try { - java.io.OutputStream stream = new FileOutputStream(MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i] + ".jpg"); + java.io.OutputStream stream = new FileOutputStream(MediaNames.THUMBNAIL_METADATA_TEST_FILES[i] + ".jpg"); bitmap.compress(Bitmap.CompressFormat.JPEG, 75, stream); stream.close(); } catch (Exception e) { - Log.e(TAG, "Fails to convert the bitmap to a JPEG file for " + MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i]); + Log.e(TAG, "Fails to convert the bitmap to a JPEG file for " + MediaNames.THUMBNAIL_METADATA_TEST_FILES[i]); hasFailed = true; Log.e(TAG, e.toString()); } } catch(Exception e) { - Log.e(TAG, "Fails to setDataSource for file " + MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i]); + Log.e(TAG, "Fails to setDataSource for file " + MediaNames.THUMBNAIL_METADATA_TEST_FILES[i]); hasFailed = true; } Thread.yield(); // Don't be evil @@ -106,7 +106,7 @@ public class MediaMetadataRetrieverTest extends AndroidTestCase { long endedAt = System.currentTimeMillis(); retriever.release(); assertTrue(!hasFailed); - Log.v(TAG, "Average processing time per thumbnail: " + (endedAt - startedAt)/MediaNames.THUMBNAIL_CAPTURE_TEST_FILES.length + " ms"); + Log.v(TAG, "Average processing time per thumbnail: " + (endedAt - startedAt)/MediaNames.THUMBNAIL_METADATA_TEST_FILES.length + " ms"); } @LargeTest @@ -115,19 +115,19 @@ public class MediaMetadataRetrieverTest extends AndroidTestCase { boolean supportWMV = MediaProfileReader.getWMVEnable(); boolean hasFailed = false; MediaMetadataRetriever retriever = new MediaMetadataRetriever(); - for(int i = 0, n = MediaNames.METADATA_RETRIEVAL_TEST_FILES.length; i < n; ++i) { + for(int i = 0, n = MediaNames.THUMBNAIL_METADATA_TEST_FILES.length; i < n; ++i) { try { - Log.v(TAG, "File " + i + ": " + MediaNames.METADATA_RETRIEVAL_TEST_FILES[i]); - if ((MediaNames.METADATA_RETRIEVAL_TEST_FILES[i].endsWith(".wma") && !supportWMA) || - (MediaNames.METADATA_RETRIEVAL_TEST_FILES[i].endsWith(".wmv") && !supportWMV) + Log.v(TAG, "File " + i + ": " + MediaNames.THUMBNAIL_METADATA_TEST_FILES[i]); + if ((MediaNames.THUMBNAIL_METADATA_TEST_FILES[i].endsWith(".wma") && !supportWMA) || + (MediaNames.THUMBNAIL_METADATA_TEST_FILES[i].endsWith(".wmv") && !supportWMV) ) { Log.v(TAG, "windows media is not supported and thus we will skip the test for this file"); continue; } - retriever.setDataSource(MediaNames.METADATA_RETRIEVAL_TEST_FILES[i]); + retriever.setDataSource(MediaNames.THUMBNAIL_METADATA_TEST_FILES[i]); extractAllSupportedMetadataValues(retriever); } catch(Exception e) { - Log.e(TAG, "Fails to setDataSource for file " + MediaNames.METADATA_RETRIEVAL_TEST_FILES[i]); + Log.e(TAG, "Fails to setDataSource for file " + MediaNames.THUMBNAIL_METADATA_TEST_FILES[i]); hasFailed = true; } Thread.yield(); // Don't be evil @@ -239,45 +239,6 @@ public class MediaMetadataRetrieverTest extends AndroidTestCase { assertTrue(!hasFailed); } - @MediumTest - public static void testIntendedUsage() { - // By default, capture frame and retrieve metadata - MediaMetadataRetriever retriever = new MediaMetadataRetriever(); - boolean hasFailed = false; - retriever.setDataSource(MediaNames.TEST_PATH_1); - assertTrue(retriever.getFrameAtTime(-1) != null); - assertTrue(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS) != null); - - // Do not capture frame or retrieve metadata - retriever.setDataSource(MediaNames.TEST_PATH_1); - if (retriever.getFrameAtTime(-1) != null) { - Log.e(TAG, "No frame expected, but is available"); - hasFailed = true; - } - if (retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS) != null) { - Log.e(TAG, "No num track metadata expected, but is available"); - hasFailed = true; - } - - // Capture frame only - retriever.setDataSource(MediaNames.TEST_PATH_1); - assertTrue(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS) == null); - - // Retriever metadata only - retriever.setDataSource(MediaNames.TEST_PATH_1); - if (retriever.getFrameAtTime(-1) != null) { - Log.e(TAG, "No frame expected, but is available"); - hasFailed = true; - } - - // Capture frame and retrieve metadata - retriever.setDataSource(MediaNames.TEST_PATH_1); - assertTrue(retriever.getFrameAtTime(-1) != null); - assertTrue(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS) != null); - retriever.release(); - assertTrue(!hasFailed); - } - // TODO: // Encode and test for the correct mix of metadata elements on a per-file basis? // We should be able to compare the actual returned metadata with the expected metadata diff --git a/media/tests/contents/media_api/goldenThumbnail.png b/media/tests/contents/media_api/goldenThumbnail.png Binary files differnew file mode 100755 index 0000000..3bb6ed2 --- /dev/null +++ b/media/tests/contents/media_api/goldenThumbnail.png diff --git a/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17.mp3 b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17.mp3 Binary files differnew file mode 100755 index 0000000..e0d6a17 --- /dev/null +++ b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17.mp3 diff --git a/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ABR.mp3 b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ABR.mp3 Binary files differnew file mode 100644 index 0000000..12f7193 --- /dev/null +++ b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ABR.mp3 diff --git a/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_CBR.mp3 b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_CBR.mp3 Binary files differnew file mode 100644 index 0000000..12f7193 --- /dev/null +++ b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_CBR.mp3 diff --git a/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V1.mp3 b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V1.mp3 Binary files differnew file mode 100644 index 0000000..29d332b --- /dev/null +++ b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V1.mp3 diff --git a/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V1_ID3V2.mp3 b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V1_ID3V2.mp3 Binary files differnew file mode 100644 index 0000000..ea52638 --- /dev/null +++ b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V1_ID3V2.mp3 diff --git a/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V2.mp3 b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V2.mp3 Binary files differnew file mode 100644 index 0000000..024039c --- /dev/null +++ b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_ID3V2.mp3 diff --git a/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_VBR.mp3 b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_VBR.mp3 Binary files differnew file mode 100644 index 0000000..12f7193 --- /dev/null +++ b/media/tests/contents/media_api/music/MP3_48KHz_128kbps_s_1_17_VBR.mp3 diff --git a/media/tests/contents/media_api/music/SHORTMP3.mp3 b/media/tests/contents/media_api/music/SHORTMP3.mp3 Binary files differnew file mode 100755 index 0000000..8b51b5d --- /dev/null +++ b/media/tests/contents/media_api/music/SHORTMP3.mp3 diff --git a/media/tests/contents/media_api/music/ants.mid b/media/tests/contents/media_api/music/ants.mid Binary files differnew file mode 100755 index 0000000..d4ead53 --- /dev/null +++ b/media/tests/contents/media_api/music/ants.mid diff --git a/media/tests/contents/media_api/music/bzk_chic.wav b/media/tests/contents/media_api/music/bzk_chic.wav Binary files differnew file mode 100755 index 0000000..bab1a6b --- /dev/null +++ b/media/tests/contents/media_api/music/bzk_chic.wav diff --git a/media/tests/contents/media_api/music/sine_200+1000Hz_44K_mo.wav b/media/tests/contents/media_api/music/sine_200+1000Hz_44K_mo.wav Binary files differnew file mode 100755 index 0000000..312b6fb --- /dev/null +++ b/media/tests/contents/media_api/music/sine_200+1000Hz_44K_mo.wav diff --git a/media/tests/contents/media_api/music/test_amr_ietf.amr b/media/tests/contents/media_api/music/test_amr_ietf.amr Binary files differnew file mode 100755 index 0000000..540794c --- /dev/null +++ b/media/tests/contents/media_api/music/test_amr_ietf.amr diff --git a/media/tests/contents/media_api/video/big-buck-bunny_trailer.webm b/media/tests/contents/media_api/video/big-buck-bunny_trailer.webm Binary files differnew file mode 100755 index 0000000..6a17395 --- /dev/null +++ b/media/tests/contents/media_api/video/big-buck-bunny_trailer.webm diff --git a/opengl/java/com/google/android/gles_jni/EGLImpl.java b/opengl/java/com/google/android/gles_jni/EGLImpl.java index f162d40..51d6ca8 100644 --- a/opengl/java/com/google/android/gles_jni/EGLImpl.java +++ b/opengl/java/com/google/android/gles_jni/EGLImpl.java @@ -85,7 +85,7 @@ public class EGLImpl implements EGL10 { eglSurfaceId = _eglCreateWindowSurface(display, config, sur, attrib_list); } else if (native_window instanceof SurfaceTexture) { eglSurfaceId = _eglCreateWindowSurfaceTexture(display, config, - ((SurfaceTexture) native_window).mSurfaceTexture, attrib_list); + (SurfaceTexture) native_window, attrib_list); } else { throw new java.lang.UnsupportedOperationException( "eglCreateWindowSurface() can only be called with an instance of " + @@ -143,7 +143,7 @@ public class EGLImpl implements EGL10 { private native int _eglCreatePbufferSurface(EGLDisplay display, EGLConfig config, int[] attrib_list); private native void _eglCreatePixmapSurface(EGLSurface sur, EGLDisplay display, EGLConfig config, Object native_pixmap, int[] attrib_list); private native int _eglCreateWindowSurface(EGLDisplay display, EGLConfig config, Object native_window, int[] attrib_list); - private native int _eglCreateWindowSurfaceTexture(EGLDisplay display, EGLConfig config, int native_window, int[] attrib_list); + private native int _eglCreateWindowSurfaceTexture(EGLDisplay display, EGLConfig config, Object native_window, int[] attrib_list); private native int _eglGetDisplay(Object native_display); private native int _eglGetCurrentContext(); private native int _eglGetCurrentDisplay(); diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index bbe146d..55f5280 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -33,13 +33,6 @@ android:excludeFromRecents="true"> </activity> - <activity android:name=".recent.RecentApplicationsActivity" - android:theme="@android:style/Theme.NoTitleBar" - android:excludeFromRecents="true" - android:launchMode="singleInstance" - android:exported="true"> - </activity> - <!-- started from UsbDeviceSettingsManager --> <activity android:name=".usb.UsbConfirmActivity" android:exported="true" diff --git a/packages/SystemUI/res/drawable-hdpi/compat_mode_help_diagram.png b/packages/SystemUI/res/drawable-hdpi/compat_mode_help_diagram.png Binary files differnew file mode 100644 index 0000000..944b1f0 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/compat_mode_help_diagram.png diff --git a/packages/SystemUI/res/drawable-hdpi/compat_mode_help_divider_bottom.9.png b/packages/SystemUI/res/drawable-hdpi/compat_mode_help_divider_bottom.9.png Binary files differnew file mode 100644 index 0000000..2e11928 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/compat_mode_help_divider_bottom.9.png diff --git a/packages/SystemUI/res/drawable-hdpi/compat_mode_help_divider_top.9.png b/packages/SystemUI/res/drawable-hdpi/compat_mode_help_divider_top.9.png Binary files differnew file mode 100644 index 0000000..58a78b7 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/compat_mode_help_divider_top.9.png diff --git a/packages/SystemUI/res/drawable-hdpi/compat_mode_help_icon.png b/packages/SystemUI/res/drawable-hdpi/compat_mode_help_icon.png Binary files differnew file mode 100644 index 0000000..46bb891 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/compat_mode_help_icon.png diff --git a/packages/SystemUI/res/drawable-hdpi/compat_mode_help_top_divider.9.png b/packages/SystemUI/res/drawable-hdpi/compat_mode_help_top_divider.9.png Binary files differnew file mode 100644 index 0000000..03a5639 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/compat_mode_help_top_divider.9.png diff --git a/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg.png b/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg.png Binary files differindex 87a67c9..23aabce 100644 --- a/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg.png +++ b/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg.png diff --git a/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_press.png b/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_press.png Binary files differnew file mode 100644 index 0000000..0b0765b --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_press.png diff --git a/packages/SystemUI/res/drawable-large-hdpi/app_icon.png b/packages/SystemUI/res/drawable-large-hdpi/app_icon.png Binary files differdeleted file mode 100644 index aedf7e7..0000000 --- a/packages/SystemUI/res/drawable-large-hdpi/app_icon.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-large-hdpi/recents_bg_protect_tile.png b/packages/SystemUI/res/drawable-large-hdpi/recents_bg_protect_tile.png Binary files differdeleted file mode 100644 index a57c27a..0000000 --- a/packages/SystemUI/res/drawable-large-hdpi/recents_bg_protect_tile.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-large-mdpi/app_icon.png b/packages/SystemUI/res/drawable-large-mdpi/app_icon.png Binary files differdeleted file mode 100644 index 50a8ac8..0000000 --- a/packages/SystemUI/res/drawable-large-mdpi/app_icon.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-large-mdpi/recents_bg_protect_tile.png b/packages/SystemUI/res/drawable-large-mdpi/recents_bg_protect_tile.png Binary files differdeleted file mode 100644 index 87c7be6..0000000 --- a/packages/SystemUI/res/drawable-large-mdpi/recents_bg_protect_tile.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-large-mdpi/recents_blue_glow.9.png b/packages/SystemUI/res/drawable-large-mdpi/recents_blue_glow.9.png Binary files differdeleted file mode 100644 index 4f4ae78..0000000 --- a/packages/SystemUI/res/drawable-large-mdpi/recents_blue_glow.9.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-large-mdpi/recents_callout_line.png b/packages/SystemUI/res/drawable-large-mdpi/recents_callout_line.png Binary files differdeleted file mode 100644 index 5f4c035..0000000 --- a/packages/SystemUI/res/drawable-large-mdpi/recents_callout_line.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-large-mdpi/recents_thumbnail_bg.png b/packages/SystemUI/res/drawable-large-mdpi/recents_thumbnail_bg.png Binary files differdeleted file mode 100644 index 87a67c9..0000000 --- a/packages/SystemUI/res/drawable-large-mdpi/recents_thumbnail_bg.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-large-mdpi/recents_thumbnail_bg_press.png b/packages/SystemUI/res/drawable-large-mdpi/recents_thumbnail_bg_press.png Binary files differdeleted file mode 100644 index a1c39e6..0000000 --- a/packages/SystemUI/res/drawable-large-mdpi/recents_thumbnail_bg_press.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-mdpi/compat_mode_help_diagram.png b/packages/SystemUI/res/drawable-mdpi/compat_mode_help_diagram.png Binary files differnew file mode 100644 index 0000000..518a5c1 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/compat_mode_help_diagram.png diff --git a/packages/SystemUI/res/drawable-mdpi/compat_mode_help_divider_bottom.9.png b/packages/SystemUI/res/drawable-mdpi/compat_mode_help_divider_bottom.9.png Binary files differnew file mode 100644 index 0000000..3712abf --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/compat_mode_help_divider_bottom.9.png diff --git a/packages/SystemUI/res/drawable-mdpi/compat_mode_help_divider_top.9.png b/packages/SystemUI/res/drawable-mdpi/compat_mode_help_divider_top.9.png Binary files differnew file mode 100644 index 0000000..a4d08c8 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/compat_mode_help_divider_top.9.png diff --git a/packages/SystemUI/res/drawable-mdpi/compat_mode_help_icon.png b/packages/SystemUI/res/drawable-mdpi/compat_mode_help_icon.png Binary files differnew file mode 100644 index 0000000..233c4df --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/compat_mode_help_icon.png diff --git a/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg.png b/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg.png Binary files differindex 87a67c9..23aabce 100644 --- a/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg.png +++ b/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg.png diff --git a/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_press.png b/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_press.png Binary files differindex a1c39e6..0b0765b 100644 --- a/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_press.png +++ b/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_press.png diff --git a/packages/SystemUI/res/drawable-nodpi/compat_mode_help_bg.png b/packages/SystemUI/res/drawable-nodpi/compat_mode_help_bg.png Binary files differindex d1d32a4..59a70ff 100644 --- a/packages/SystemUI/res/drawable-nodpi/compat_mode_help_bg.png +++ b/packages/SystemUI/res/drawable-nodpi/compat_mode_help_bg.png diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/app_icon.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/app_icon.png Binary files differdeleted file mode 100644 index aedf7e7..0000000 --- a/packages/SystemUI/res/drawable-sw600dp-hdpi/app_icon.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/app_icon.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/app_icon.png Binary files differdeleted file mode 100644 index 50a8ac8..0000000 --- a/packages/SystemUI/res/drawable-sw600dp-mdpi/app_icon.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable/compat_mode_help_bg.png b/packages/SystemUI/res/drawable/compat_mode_help_bg.png Binary files differnew file mode 100644 index 0000000..87d8c41 --- /dev/null +++ b/packages/SystemUI/res/drawable/compat_mode_help_bg.png diff --git a/packages/SystemUI/res/drawable/compat_mode_help_diagram.png b/packages/SystemUI/res/drawable/compat_mode_help_diagram.png Binary files differdeleted file mode 100644 index e212231..0000000 --- a/packages/SystemUI/res/drawable/compat_mode_help_diagram.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable/compat_mode_help_icon.png b/packages/SystemUI/res/drawable/compat_mode_help_icon.png Binary files differdeleted file mode 100644 index 03bbef9..0000000 --- a/packages/SystemUI/res/drawable/compat_mode_help_icon.png +++ /dev/null diff --git a/packages/SystemUI/res/layout-land/status_bar_recent_item.xml b/packages/SystemUI/res/layout-land/status_bar_recent_item.xml index ce72f04..be4f1d7 100644 --- a/packages/SystemUI/res/layout-land/status_bar_recent_item.xml +++ b/packages/SystemUI/res/layout-land/status_bar_recent_item.xml @@ -39,8 +39,8 @@ android:layout_height="wrap_content" android:layout_alignLeft="@id/app_thumbnail" android:layout_alignTop="@id/app_thumbnail" - android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_border_width" - android:layout_marginTop="@dimen/status_bar_recents_thumbnail_border_height" + android:layout_marginTop="@dimen/status_bar_recents_app_icon_top_margin" + android:layout_marginLeft="@dimen/status_bar_recents_app_icon_left_margin" android:maxWidth="@dimen/status_bar_recents_thumbnail_max_width" android:maxHeight="@dimen/status_bar_recents_thumbnail_max_height" android:adjustViewBounds="true" @@ -56,7 +56,7 @@ android:layout_alignLeft="@id/app_thumbnail" android:layout_below="@id/app_thumbnail" android:layout_marginTop="@dimen/status_bar_recents_text_description_padding" - android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_border_width" + android:layout_marginLeft="@dimen/recents_thumbnail_bg_padding_left" android:singleLine="true" android:ellipsize="marquee" /> @@ -71,7 +71,7 @@ android:layout_alignLeft="@id/app_thumbnail" android:layout_below="@id/app_label" android:layout_marginTop="@dimen/status_bar_recents_text_description_padding" - android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_border_width" + android:layout_marginLeft="@dimen/recents_thumbnail_bg_padding_left" android:singleLine="true" android:ellipsize="marquee" /> diff --git a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml index 75f5ee4..4a80489 100644 --- a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml +++ b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml @@ -27,10 +27,9 @@ <FrameLayout android:id="@+id/recents_bg_protect" android:background="@drawable/recents_bg_protect_tile" - android:layout_width="wrap_content" + android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentBottom="true" - android:layout_alignParentRight="true" android:paddingBottom="@*android:dimen/status_bar_height" android:clipToPadding="false" android:clipChildren="false"> diff --git a/packages/SystemUI/res/layout/status_bar_recent_item.xml b/packages/SystemUI/res/layout-port/status_bar_recent_item.xml index cd42d7e..76965c9 100644 --- a/packages/SystemUI/res/layout/status_bar_recent_item.xml +++ b/packages/SystemUI/res/layout-port/status_bar_recent_item.xml @@ -36,53 +36,52 @@ <ImageView android:id="@+id/app_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_alignParentLeft="true" - android:layout_alignParentTop="true" - android:layout_marginLeft="131dip" - android:layout_marginTop="13dip" + android:layout_alignLeft="@id/app_thumbnail" + android:layout_alignTop="@id/app_thumbnail" + android:layout_marginLeft="@dimen/status_bar_recents_app_icon_left_margin" + android:layout_marginTop="@dimen/status_bar_recents_app_icon_top_margin" android:maxWidth="@dimen/status_bar_recents_thumbnail_max_width" android:maxHeight="@dimen/status_bar_recents_thumbnail_max_height" android:adjustViewBounds="true" /> - <View android:id="@+id/recents_callout_line" - android:layout_width="97dip" - android:layout_height="1dip" - android:layout_alignParentTop="true" - android:layout_marginTop="61dip" - android:layout_alignParentLeft="true" - android:layout_marginLeft="16dip" - android:layout_toLeftOf="@id/app_thumbnail" - android:layout_marginRight="3dip" - android:background="@drawable/recents_callout_line" - /> - <TextView android:id="@+id/app_label" - android:layout_width="97dip" + android:layout_width="@dimen/status_bar_recents_app_label_width" android:layout_height="wrap_content" - android:textSize="@dimen/status_bar_recents_app_description_text_size" + android:textSize="@dimen/status_bar_recents_app_label_text_size" android:fadingEdge="horizontal" android:fadingEdgeLength="@dimen/status_bar_recents_fading_edge_length" android:scrollHorizontally="true" android:layout_alignParentLeft="true" - android:layout_alignParentTop="true" - android:layout_marginLeft="16dip" - android:layout_marginTop="32dip" + android:layout_alignTop="@id/app_icon" + android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin" android:singleLine="true" android:ellipsize="marquee" /> + <View android:id="@+id/recents_callout_line" + android:layout_width="@dimen/status_bar_recents_app_label_width" + android:layout_height="1dip" + android:layout_alignParentLeft="true" + android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin" + android:layout_toLeftOf="@id/app_thumbnail" + android:layout_below="@id/app_label" + android:layout_marginRight="3dip" + android:layout_marginTop="3dip" + android:background="@drawable/recents_callout_line" + /> + <TextView android:id="@+id/app_description" - android:layout_width="97dip" + android:layout_width="@dimen/status_bar_recents_app_label_width" android:layout_height="wrap_content" android:textSize="@dimen/status_bar_recents_app_description_text_size" android:fadingEdge="horizontal" android:fadingEdgeLength="@dimen/status_bar_recents_fading_edge_length" android:scrollHorizontally="true" android:layout_alignParentLeft="true" - android:layout_alignParentTop="true" - android:layout_marginLeft="16dip" - android:layout_marginTop="61dip" + android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin" + android:layout_below="@id/recents_callout_line" + android:layout_marginTop="3dip" android:singleLine="true" android:ellipsize="marquee" /> diff --git a/packages/SystemUI/res/layout/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml index 703cbc1..9391f9d 100644 --- a/packages/SystemUI/res/layout/status_bar_recent_panel.xml +++ b/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml @@ -22,12 +22,12 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/recents_root" android:layout_height="match_parent" - android:layout_width="wrap_content"> + android:layout_width="match_parent"> <FrameLayout android:id="@+id/recents_bg_protect" android:background="@drawable/recents_bg_protect_tile" - android:layout_width="wrap_content" + android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentBottom="true" android:paddingBottom="@*android:dimen/status_bar_height" @@ -35,9 +35,9 @@ android:clipChildren="false"> <LinearLayout android:id="@+id/recents_glow" - android:layout_width="wrap_content" + android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginBottom="-49dip" + android:layout_marginBottom="0dp" android:layout_gravity="bottom" android:background="@drawable/recents_blue_glow" android:orientation="horizontal" @@ -47,7 +47,7 @@ <com.android.systemui.recent.RecentsVerticalScrollView android:id="@+id/recents_container" android:layout_width="@dimen/status_bar_recents_width" android:layout_height="wrap_content" - android:layout_marginRight="@dimen/status_bar_recents_right_glow_margin" + android:layout_marginRight="0dp" android:divider="@null" android:stackFromBottom="true" android:fadingEdge="vertical" diff --git a/packages/SystemUI/res/layout-sw600dp/compat_mode_help.xml b/packages/SystemUI/res/layout-sw600dp/compat_mode_help.xml index df3c5a3..d29e495 100644 --- a/packages/SystemUI/res/layout-sw600dp/compat_mode_help.xml +++ b/packages/SystemUI/res/layout-sw600dp/compat_mode_help.xml @@ -27,51 +27,62 @@ android:id="@+id/header" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginLeft="160dp" + android:layout_marginLeft="80dp" android:layout_marginTop="80dp" + android:layout_marginRight="80dp" android:textSize="60sp" android:maxLines="1" android:shadowRadius="8" android:shadowColor="#FF000000" android:text="@string/compat_mode_help_header" + android:background="@drawable/compat_mode_help_divider_top" /> <ImageView android:id="@+id/diagram" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginLeft="160dp" - android:layout_marginTop="80dp" android:layout_centerInParent="true" android:src="@drawable/compat_mode_help_diagram" /> - <TextView - android:id="@+id/explanation" + <RelativeLayout + android:orientation="horizontal" android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginBottom="80dp" - android:layout_marginRight="240dp" + android:layout_height="190dp" + android:background="@drawable/compat_mode_help_divider_bottom" + android:layout_marginBottom="55dp" + android:layout_marginRight="80dp" android:layout_alignLeft="@id/header" android:layout_alignParentBottom="true" - android:shadowRadius="4" - android:shadowColor="#FF000000" - android:textSize="28sp" - android:text="@string/compat_mode_help_body" - /> - <ImageView - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginRight="80dp" - android:layout_alignBottom="@id/explanation" - android:layout_alignParentRight="true" - android:src="@drawable/compat_mode_help_icon" - /> + > + <ImageView + android:id="@+id/icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentRight="true" + android:layout_centerVertical="true" + android:src="@drawable/compat_mode_help_icon" + /> + <TextView + android:id="@+id/explanation" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_centerVertical="true" + android:layout_alignParentLeft="true" + android:layout_toLeftOf="@id/icon" + android:layout_marginRight="10dp" + android:shadowRadius="4" + android:shadowColor="#FF000000" + android:textSize="28sp" + android:text="@string/compat_mode_help_body" + /> + </RelativeLayout> <Button android:id="@+id/button" android:layout_width="208dp" android:layout_height="48dp" android:layout_alignLeft="@id/header" android:layout_alignParentBottom="true" - android:layout_marginBottom="10dp" + android:layout_marginBottom="20dp" android:textSize="28sp" android:text="@android:string/ok" /> diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_compat_mode_panel.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_compat_mode_panel.xml index c151565..a33741e 100644 --- a/packages/SystemUI/res/layout-sw600dp/status_bar_compat_mode_panel.xml +++ b/packages/SystemUI/res/layout-sw600dp/status_bar_compat_mode_panel.xml @@ -31,13 +31,13 @@ android:orientation="vertical" android:padding="10dp" > - <RadioButton android:id="@+id/compat_mode_on_radio" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/compat_mode_on" /> <RadioButton android:id="@+id/compat_mode_off_radio" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/compat_mode_off" /> + <RadioButton android:id="@+id/compat_mode_on_radio" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/compat_mode_on" /> </RadioGroup> </com.android.systemui.statusbar.tablet.CompatModePanel> diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml index cd42d7e..9687866 100644 --- a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml +++ b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml @@ -36,53 +36,53 @@ <ImageView android:id="@+id/app_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_alignParentLeft="true" - android:layout_alignParentTop="true" - android:layout_marginLeft="131dip" - android:layout_marginTop="13dip" + android:layout_alignLeft="@id/app_thumbnail" + android:layout_alignTop="@id/app_thumbnail" + android:layout_marginLeft="@dimen/status_bar_recents_app_icon_left_margin" + android:layout_marginTop="@dimen/status_bar_recents_app_icon_top_margin" android:maxWidth="@dimen/status_bar_recents_thumbnail_max_width" android:maxHeight="@dimen/status_bar_recents_thumbnail_max_height" android:adjustViewBounds="true" /> - <View android:id="@+id/recents_callout_line" - android:layout_width="97dip" - android:layout_height="1dip" - android:layout_alignParentTop="true" - android:layout_marginTop="61dip" - android:layout_alignParentLeft="true" - android:layout_marginLeft="16dip" - android:layout_toLeftOf="@id/app_thumbnail" - android:layout_marginRight="3dip" - android:background="@drawable/recents_callout_line" - /> - <TextView android:id="@+id/app_label" - android:layout_width="97dip" + android:layout_width="@dimen/status_bar_recents_app_label_width" android:layout_height="wrap_content" - android:textSize="@dimen/status_bar_recents_app_description_text_size" + android:textSize="@dimen/status_bar_recents_app_label_text_size" android:fadingEdge="horizontal" android:fadingEdgeLength="@dimen/status_bar_recents_fading_edge_length" android:scrollHorizontally="true" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" - android:layout_marginLeft="16dip" + android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin" android:layout_marginTop="32dip" android:singleLine="true" android:ellipsize="marquee" /> + <View android:id="@+id/recents_callout_line" + android:layout_width="@dimen/status_bar_recents_app_label_width" + android:layout_height="1dip" + android:layout_below="@id/app_label" + android:layout_marginTop="3dip" + android:layout_alignParentLeft="true" + android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin" + android:layout_toLeftOf="@id/app_thumbnail" + android:layout_marginRight="3dip" + android:background="@drawable/recents_callout_line" + /> + <TextView android:id="@+id/app_description" - android:layout_width="97dip" + android:layout_width="@dimen/status_bar_recents_app_label_width" android:layout_height="wrap_content" android:textSize="@dimen/status_bar_recents_app_description_text_size" android:fadingEdge="horizontal" android:fadingEdgeLength="@dimen/status_bar_recents_fading_edge_length" android:scrollHorizontally="true" android:layout_alignParentLeft="true" - android:layout_alignParentTop="true" - android:layout_marginLeft="16dip" - android:layout_marginTop="61dip" + android:layout_below="@id/recents_callout_line" + android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin" + android:layout_marginTop="3dip" android:singleLine="true" android:ellipsize="marquee" /> diff --git a/packages/SystemUI/res/layout/recent_apps_activity.xml b/packages/SystemUI/res/layout/recent_apps_activity.xml deleted file mode 100644 index ec661e8..0000000 --- a/packages/SystemUI/res/layout/recent_apps_activity.xml +++ /dev/null @@ -1,55 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** Copyright 2008, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> - -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical"> - - <!-- Title --> - <TextView - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:gravity="center" - android:textAppearance="?android:attr/textAppearanceSmall" - android:textColor="#80FFFFFF" - android:textStyle="bold" - android:singleLine="true" - android:text="@string/recent_tasks_title" - android:visibility="gone"/> - - <!-- This is only intended to be visible when carousel is invisible --> - <TextView - android:id="@+id/no_applications_message" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:textAppearance="?android:attr/textAppearanceSmall" - android:text="@string/recent_tasks_empty" - android:visibility="gone"/> - - <com.android.systemui.recent.RecentApplicationsCarouselView - android:id="@+id/carousel" - android:layout_width="match_parent" - android:layout_height="0dip" - android:layout_weight="1"> - </com.android.systemui.recent.RecentApplicationsCarouselView> - -</LinearLayout> diff --git a/packages/SystemUI/res/layout/recents_detail_view.xml b/packages/SystemUI/res/layout/recents_detail_view.xml deleted file mode 100644 index 879d0f2..0000000 --- a/packages/SystemUI/res/layout/recents_detail_view.xml +++ /dev/null @@ -1,40 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** Copyright 2008, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> - -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical"> - - <!-- Application Title --> - <TextView android:id="@+id/app_title" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:textAppearance="?android:attr/textAppearanceMedium" - android:singleLine="true"/> - - <!-- Application Details --> - <TextView - android:id="@+id/app_description" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:textAppearance="?android:attr/textAppearanceSmall"/> - -</LinearLayout> diff --git a/packages/SystemUI/res/values-hdpi/dimens.xml b/packages/SystemUI/res/values-hdpi/dimens.xml new file mode 100644 index 0000000..741b75a --- /dev/null +++ b/packages/SystemUI/res/values-hdpi/dimens.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + * Copyright (c) 2011, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ +--> +<resources> + <!-- Offsets for rendering thumbnails over drawable recents_thumbnail_bg --> + <dimen name="recents_thumbnail_bg_padding_left">6px</dimen> + <dimen name="recents_thumbnail_bg_padding_top">7px</dimen> + <dimen name="recents_thumbnail_bg_padding_right">6px</dimen> + <dimen name="recents_thumbnail_bg_padding_bottom">6px</dimen> +</resources> diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml index 6f1453e..0219a77 100644 --- a/packages/SystemUI/res/values-land/dimens.xml +++ b/packages/SystemUI/res/values-land/dimens.xml @@ -23,15 +23,17 @@ <!-- Width of a recent app view, including all content --> <dimen name="status_bar_recents_thumbnail_view_width">156dp</dimen> <!-- How far the thumbnail for a recent app appears from left edge --> - <dimen name="status_bar_recents_thumbnail_left_margin">0dp</dimen> + <dimen name="status_bar_recents_thumbnail_left_margin">8dp</dimen> + <!-- How far the thumbnail for a recent app appears from top edge --> + <dimen name="status_bar_recents_thumbnail_top_margin">12dp</dimen> <!-- Width of scrollable area in recents --> <dimen name="status_bar_recents_width">128dp</dimen> - <!-- Thumbnail border width --> - <dimen name="status_bar_recents_thumbnail_border_width">8dp</dimen> - <!-- Thumbnail border height --> - <dimen name="status_bar_recents_thumbnail_border_height">12dp</dimen> <!-- Padding for text descriptions --> <dimen name="status_bar_recents_text_description_padding">8dp</dimen> + <!-- Width of application label text --> + <dimen name="status_bar_recents_app_label_width">97dip</dimen> + <!-- Left margin of application label text --> + <dimen name="status_bar_recents_app_label_left_margin">16dip</dimen> <!-- Margin between recents container and glow on the right --> <dimen name="status_bar_recents_right_glow_margin">0dip</dimen> </resources> diff --git a/packages/SystemUI/res/values-large/dimens.xml b/packages/SystemUI/res/values-large/dimens.xml index f8a4a1c..9d89e21 100644 --- a/packages/SystemUI/res/values-large/dimens.xml +++ b/packages/SystemUI/res/values-large/dimens.xml @@ -22,32 +22,6 @@ <dimen name="status_bar_panel_bottom_offset">36dp</dimen> <!-- gap on either side of status bar notification icons --> <dimen name="status_bar_icon_padding">8dp</dimen> - - <!-- Recent Applications parameters --> - <!-- Width of a recent app view, including all content --> - <dimen name="status_bar_recents_thumbnail_view_width">156dp</dimen> - <!-- How far the thumbnail for a recent app appears from left edge --> - <dimen name="status_bar_recents_thumbnail_left_margin">110dp</dimen> - <!-- Upper width limit for application icon --> - <dimen name="status_bar_recents_thumbnail_max_width">64dp</dimen> - <!-- Upper height limit for application icon --> - <dimen name="status_bar_recents_thumbnail_max_height">64dp</dimen> - <!-- Width of scrollable area in recents --> - <dimen name="status_bar_recents_width">356dp</dimen> - <!-- Thumbnail border width --> - <dimen name="status_bar_recents_thumbnail_border_width">12dp</dimen> - <!-- Thumbnail border height --> - <dimen name="status_bar_recents_thumbnail_border_height">12dp</dimen> - <!-- Padding for text descriptions --> - <dimen name="status_bar_recents_text_description_padding">8dp</dimen> - <!-- Size of application label text --> - <dimen name="status_bar_recents_app_label_text_size">18dip</dimen> - <!-- Size of application description text --> - <dimen name="status_bar_recents_app_description_text_size">18dip</dimen> - <!-- Size of fading edge for scroll effect --> - <dimen name="status_bar_recents_fading_edge_length">20dip</dimen> - <!-- Margin between recents container and glow on the right --> - <dimen name="status_bar_recents_right_glow_margin">100dip</dimen> </resources> diff --git a/packages/SystemUI/res/values-mdpi/dimens.xml b/packages/SystemUI/res/values-mdpi/dimens.xml new file mode 100644 index 0000000..741b75a --- /dev/null +++ b/packages/SystemUI/res/values-mdpi/dimens.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + * Copyright (c) 2011, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ +--> +<resources> + <!-- Offsets for rendering thumbnails over drawable recents_thumbnail_bg --> + <dimen name="recents_thumbnail_bg_padding_left">6px</dimen> + <dimen name="recents_thumbnail_bg_padding_top">7px</dimen> + <dimen name="recents_thumbnail_bg_padding_right">6px</dimen> + <dimen name="recents_thumbnail_bg_padding_bottom">6px</dimen> +</resources> diff --git a/packages/SystemUI/res/values-port/dimens.xml b/packages/SystemUI/res/values-port/dimens.xml new file mode 100644 index 0000000..54c25fa --- /dev/null +++ b/packages/SystemUI/res/values-port/dimens.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + * Copyright (c) 2006, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ +--> +<resources> + <!-- Recent Applications parameters --> + <!-- Width of a recent app view, including all content --> + <dimen name="status_bar_recents_thumbnail_view_width">156dp</dimen> + <!-- How far the thumbnail for a recent app appears from left edge --> + <dimen name="status_bar_recents_thumbnail_left_margin">110dp</dimen> + <!-- Width of scrollable area in recents --> + <dimen name="status_bar_recents_width">356dp</dimen> + <!-- Padding for text descriptions --> + <dimen name="status_bar_recents_text_description_padding">8dp</dimen> + <!-- Width of application label text --> + <dimen name="status_bar_recents_app_label_width">97dip</dimen> + <!-- Left margin of application label text --> + <dimen name="status_bar_recents_app_label_left_margin">16dip</dimen> + <!-- Margin between recents container and glow on the right --> + <dimen name="status_bar_recents_right_glow_margin">100dip</dimen> +</resources> diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml index 944e0ee..b4fd8ab 100644 --- a/packages/SystemUI/res/values-sw600dp/dimens.xml +++ b/packages/SystemUI/res/values-sw600dp/dimens.xml @@ -28,4 +28,40 @@ <dimen name="notification_panel_min_height">770dp</dimen> <!-- Bottom margin (from display edge) for status bar panels --> <dimen name="panel_float">56dp</dimen> + + <!-- Recent Applications parameters --> + <!-- Width of a recent app view, including all content --> + <dimen name="status_bar_recents_thumbnail_view_width">156dp</dimen> + <!-- How far the thumbnail for a recent app appears from left edge --> + <dimen name="status_bar_recents_thumbnail_left_margin">110dp</dimen> + <!-- Upper width limit for application icon --> + <dimen name="status_bar_recents_thumbnail_max_width">64dp</dimen> + <!-- Upper height limit for application icon --> + <dimen name="status_bar_recents_thumbnail_max_height">64dp</dimen> + <!-- Width of scrollable area in recents --> + <dimen name="status_bar_recents_width">356dp</dimen> + <!-- Padding for text descriptions --> + <dimen name="status_bar_recents_text_description_padding">8dp</dimen> + <!-- Size of application label text --> + <dimen name="status_bar_recents_app_label_text_size">18dip</dimen> + <!-- Size of application description text --> + <dimen name="status_bar_recents_app_description_text_size">18dip</dimen> + <!-- Width of application label text --> + <dimen name="status_bar_recents_app_label_width">97dip</dimen> + <!-- Left margin for application label --> + <dimen name="status_bar_recents_app_label_left_margin">16dip</dimen> + <!-- Size of fading edge for scroll effect --> + <dimen name="status_bar_recents_fading_edge_length">20dip</dimen> + <!-- Margin between recents container and glow on the right --> + <dimen name="status_bar_recents_right_glow_margin">100dip</dimen> + + <!-- Offsets for rendering thumbnails over drawable recents_thumbnail_bg --> + <dimen name="recents_thumbnail_bg_padding_left">15px</dimen> + <dimen name="recents_thumbnail_bg_padding_top">8px</dimen> + <dimen name="recents_thumbnail_bg_padding_right">12px</dimen> + <dimen name="recents_thumbnail_bg_padding_bottom">8px</dimen> + + <!-- Where to place the app icon over the thumbnail --> + <dimen name="status_bar_recents_app_icon_left_margin">13dp</dimen> + <dimen name="status_bar_recents_app_icon_top_margin">13dp</dimen> </resources> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 83eaaa8..fc35a48 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -20,22 +20,14 @@ <dimen name="status_bar_edge_ignore">5dp</dimen> <!-- Recent Applications parameters --> - <!-- Width of a recent app view, including all content --> - <dimen name="status_bar_recents_thumbnail_view_width">156dp</dimen> - <!-- How far the thumbnail for a recent app appears from left edge --> - <dimen name="status_bar_recents_thumbnail_left_margin">110dp</dimen> <!-- Upper width limit for application icon --> <dimen name="status_bar_recents_thumbnail_max_width">64dp</dimen> <!-- Upper height limit for application icon --> <dimen name="status_bar_recents_thumbnail_max_height">64dp</dimen> - <!-- Width of scrollable area in recents --> - <dimen name="status_bar_recents_width">356dp</dimen> - <!-- Thumbnail border width --> - <dimen name="status_bar_recents_thumbnail_border_width">12dp</dimen> - <!-- Thumbnail border height --> - <dimen name="status_bar_recents_thumbnail_border_height">12dp</dimen> - <!-- Padding for text descriptions --> - <dimen name="status_bar_recents_text_description_padding">8dp</dimen> + <!-- Where to place the app icon over the thumbnail --> + <dimen name="status_bar_recents_app_icon_left_margin">13dp</dimen> + <dimen name="status_bar_recents_app_icon_top_margin">13dp</dimen> + <!-- Size of application label text --> <dimen name="status_bar_recents_app_label_text_size">18dip</dimen> <!-- Size of application description text --> diff --git a/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java b/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java index b876075..49a65d8 100644 --- a/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java +++ b/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java @@ -36,14 +36,16 @@ import android.view.View; View mScrimView; View mContentView; AnimatorSet mContentAnim; + Animator.AnimatorListener mListener; // the panel will start to appear this many px from the end final int HYPERSPACE_OFFRAMP = 200; - public Choreographer(View root, View scrim, View content) { + public Choreographer(View root, View scrim, View content, Animator.AnimatorListener listener) { mRootView = root; mScrimView = scrim; mContentView = content; + mListener = listener; } void createAnimation(boolean appearing) { @@ -86,6 +88,9 @@ import android.view.View; .with(posAnim); mContentAnim.setDuration(appearing ? OPEN_DURATION : CLOSE_DURATION); mContentAnim.addListener(this); + if (mListener != null) { + mContentAnim.addListener(mListener); + } } void startAnimation(boolean appearing) { diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java index 194c9d1..3dbcc59 100644 --- a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java +++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java @@ -16,7 +16,7 @@ package com.android.systemui.recent; -import com.android.systemui.recent.RecentsPanelView.ActvityDescriptionAdapter; +import com.android.systemui.recent.RecentsPanelView.ActivityDescriptionAdapter; import android.animation.Animator; import android.animation.Animator.AnimatorListener; @@ -49,7 +49,7 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView private static final float THRESHHOLD = 50; private static final boolean DEBUG_INVALIDATE = false; private LinearLayout mLinearLayout; - private ActvityDescriptionAdapter mAdapter; + private ActivityDescriptionAdapter mAdapter; private RecentsCallback mCallback; protected int mLastScrollPosition; private View mCurrentView; @@ -273,7 +273,7 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView } } - public void setAdapter(ActvityDescriptionAdapter adapter) { + public void setAdapter(ActivityDescriptionAdapter adapter) { mAdapter = adapter; mAdapter.registerDataSetObserver(new DataSetObserver() { public void onChanged() { diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java index e2b3446..b8dc63d 100644 --- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java @@ -19,6 +19,7 @@ package com.android.systemui.recent; import java.util.ArrayList; import java.util.List; +import android.animation.Animator; import android.animation.LayoutTransition; import android.app.ActivityManager; import android.content.Context; @@ -52,27 +53,33 @@ import android.widget.RelativeLayout; import android.widget.TextView; import com.android.systemui.R; +import com.android.systemui.statusbar.StatusBar; +import com.android.systemui.statusbar.phone.PhoneStatusBar; import com.android.systemui.statusbar.tablet.StatusBarPanel; import com.android.systemui.statusbar.tablet.TabletStatusBar; public class RecentsPanelView extends RelativeLayout - implements OnItemClickListener, RecentsCallback, StatusBarPanel { - private static final int GLOW_PADDING = 15; + implements OnItemClickListener, RecentsCallback, StatusBarPanel, Animator.AnimatorListener { static final String TAG = "RecentsListView"; - static final boolean DEBUG = TabletStatusBar.DEBUG; + static final boolean DEBUG = TabletStatusBar.DEBUG || PhoneStatusBar.DEBUG; private static final int DISPLAY_TASKS = 20; private static final int MAX_TASKS = DISPLAY_TASKS + 1; // allow extra for non-apps - private TabletStatusBar mBar; + private StatusBar mBar; private ArrayList<ActivityDescription> mActivityDescriptions; private int mIconDpi; private View mRecentsScrim; private View mRecentsGlowView; private View mRecentsContainer; private Bitmap mGlowBitmap; + // TODO: add these widgets attributes to the layout file + private int mGlowBitmapPaddingLeftPx; + private int mGlowBitmapPaddingTopPx; + private int mGlowBitmapPaddingRightPx; + private int mGlowBitmapPaddingBottomPx; private boolean mShowing; private Choreographer mChoreo; private View mRecentsDismissButton; - private ActvityDescriptionAdapter mListAdapter; + private ActivityDescriptionAdapter mListAdapter; /* package */ final static class ActivityDescription { int taskId; // application task id for curating apps @@ -108,10 +115,10 @@ public class RecentsPanelView extends RelativeLayout ActivityDescription activityDescription; } - /* package */ final class ActvityDescriptionAdapter extends BaseAdapter { + /* package */ final class ActivityDescriptionAdapter extends BaseAdapter { private LayoutInflater mInflater; - public ActvityDescriptionAdapter(Context context) { + public ActivityDescriptionAdapter(Context context) { mInflater = LayoutInflater.from(context); } @@ -183,6 +190,26 @@ public class RecentsPanelView extends RelativeLayout } } + public void onAnimationCancel(Animator animation) { + } + + public void onAnimationEnd(Animator animation) { + if (mShowing) { + final LayoutTransition transitioner = new LayoutTransition(); + ((ViewGroup)mRecentsContainer).setLayoutTransition(transitioner); + createCustomAnimations(transitioner); + } else { + ((ViewGroup)mRecentsContainer).setLayoutTransition(null); + } + } + + public void onAnimationRepeat(Animator animation) { + } + + public void onAnimationStart(Animator animation) { + } + + /** * We need to be aligned at the bottom. LinearLayout can't do this, so instead, * let LinearLayout do all the hard work, and then shift everything down to the bottom. @@ -201,7 +228,7 @@ public class RecentsPanelView extends RelativeLayout return mShowing; } - public void setBar(TabletStatusBar bar) { + public void setBar(StatusBar bar) { mBar = bar; } @@ -217,7 +244,16 @@ public class RecentsPanelView extends RelativeLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE; mIconDpi = xlarge ? DisplayMetrics.DENSITY_HIGH : res.getDisplayMetrics().densityDpi; + mGlowBitmap = BitmapFactory.decodeResource(res, R.drawable.recents_thumbnail_bg); + mGlowBitmapPaddingLeftPx = + res.getDimensionPixelSize(R.dimen.recents_thumbnail_bg_padding_left); + mGlowBitmapPaddingTopPx = + res.getDimensionPixelSize(R.dimen.recents_thumbnail_bg_padding_top); + mGlowBitmapPaddingRightPx = + res.getDimensionPixelSize(R.dimen.recents_thumbnail_bg_padding_right); + mGlowBitmapPaddingBottomPx = + res.getDimensionPixelSize(R.dimen.recents_thumbnail_bg_padding_bottom); } @Override @@ -225,7 +261,7 @@ public class RecentsPanelView extends RelativeLayout super.onFinishInflate(); mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); mRecentsContainer = findViewById(R.id.recents_container); - mListAdapter = new ActvityDescriptionAdapter(mContext); + mListAdapter = new ActivityDescriptionAdapter(mContext); if (mRecentsContainer instanceof RecentsListView) { RecentsListView listView = (RecentsListView) mRecentsContainer; listView.setAdapter(mListAdapter); @@ -246,13 +282,10 @@ public class RecentsPanelView extends RelativeLayout throw new IllegalArgumentException("missing RecentsListView/RecentsScrollView"); } - final LayoutTransition transitioner = new LayoutTransition(); - ((ViewGroup)mRecentsContainer).setLayoutTransition(transitioner); - createCustomAnimations(transitioner); mRecentsGlowView = findViewById(R.id.recents_glow); mRecentsScrim = (View) findViewById(R.id.recents_bg_protect); - mChoreo = new Choreographer(this, mRecentsScrim, mRecentsGlowView); + mChoreo = new Choreographer(this, mRecentsScrim, mRecentsGlowView, this); mRecentsDismissButton = findViewById(R.id.recents_dismiss_button); mRecentsDismissButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { @@ -402,10 +435,9 @@ public class RecentsPanelView extends RelativeLayout Log.v(TAG, "Source thumb: " + srcWidth + "x" + srcHeight); canvas.drawBitmap(thumbnail, new Rect(0, 0, srcWidth-1, srcHeight-1), - new RectF(GLOW_PADDING, - GLOW_PADDING - 7.0f, - outBitmap.getWidth() - GLOW_PADDING + 3.0f, - outBitmap.getHeight() - GLOW_PADDING + 7.0f), paint); + new RectF(mGlowBitmapPaddingLeftPx, mGlowBitmapPaddingTopPx, + outBitmap.getWidth() - mGlowBitmapPaddingRightPx, + outBitmap.getHeight() - mGlowBitmapPaddingBottomPx), paint); } return outBitmap; } diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java index 54ec6b5..6a962cb 100644 --- a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java +++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java @@ -16,7 +16,7 @@ package com.android.systemui.recent; -import com.android.systemui.recent.RecentsPanelView.ActvityDescriptionAdapter; +import com.android.systemui.recent.RecentsPanelView.ActivityDescriptionAdapter; import android.animation.Animator; import android.animation.Animator.AnimatorListener; @@ -49,7 +49,7 @@ public class RecentsVerticalScrollView extends ScrollView private static final float THRESHHOLD = 50; private static final boolean DEBUG_INVALIDATE = false; private LinearLayout mLinearLayout; - private ActvityDescriptionAdapter mAdapter; + private ActivityDescriptionAdapter mAdapter; private RecentsCallback mCallback; protected int mLastScrollPosition; private View mCurrentView; @@ -275,7 +275,7 @@ public class RecentsVerticalScrollView extends ScrollView } } - public void setAdapter(ActvityDescriptionAdapter adapter) { + public void setAdapter(ActivityDescriptionAdapter adapter) { mAdapter = adapter; mAdapter.registerDataSetObserver(new DataSetObserver() { public void onChanged() { diff --git a/packages/SystemUI/src/com/android/systemui/recent/carousel/RecentApplicationsActivity.java b/packages/SystemUI/src/com/android/systemui/recent/carousel/RecentApplicationsActivity.java deleted file mode 100644 index 45e230f..0000000 --- a/packages/SystemUI/src/com/android/systemui/recent/carousel/RecentApplicationsActivity.java +++ /dev/null @@ -1,532 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package com.android.systemui.recent.carousel; - -import com.android.systemui.R; - -import com.android.ex.carousel.CarouselView; -import com.android.ex.carousel.CarouselViewHelper; -import com.android.ex.carousel.CarouselRS.CarouselCallback; -import com.android.ex.carousel.CarouselViewHelper.DetailTextureParameters; - -import java.util.ArrayList; -import java.util.List; - -import android.app.Activity; -import android.app.ActivityManager; -import android.app.ActivityManagerNative; -import android.app.IActivityManager; -import android.app.IThumbnailReceiver; -import android.app.ActivityManager.RunningTaskInfo; -import android.content.ActivityNotFoundException; -import android.content.Context; -import android.content.Intent; -import android.content.pm.ActivityInfo; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Canvas; -import android.graphics.Matrix; -import android.graphics.Paint; -import android.graphics.PaintFlagsDrawFilter; -import android.graphics.PorterDuffXfermode; -import android.graphics.PorterDuff; -import android.graphics.Bitmap.Config; -import android.graphics.drawable.Drawable; -import android.graphics.PixelFormat; -import android.os.Bundle; -import android.os.RemoteException; -import android.util.Log; -import android.view.View; -import android.view.View.MeasureSpec; -import android.widget.TextView; - -public class RecentApplicationsActivity extends Activity { - private static final String TAG = "RecentApplicationsActivity"; - private static boolean DBG = false; - private static final int CARD_SLOTS = 56; - private static final int VISIBLE_SLOTS = 7; - private static final int MAX_TASKS = VISIBLE_SLOTS * 2; - - // TODO: these should be configurable - private static final int DETAIL_TEXTURE_MAX_WIDTH = 200; - private static final int DETAIL_TEXTURE_MAX_HEIGHT = 80; - private static final int TEXTURE_WIDTH = 256; - private static final int TEXTURE_HEIGHT = 256; - - private ActivityManager mActivityManager; - private List<RunningTaskInfo> mRunningTaskList; - private boolean mPortraitMode = true; - private ArrayList<ActivityDescription> mActivityDescriptions - = new ArrayList<ActivityDescription>(); - private CarouselView mCarouselView; - private LocalCarouselViewHelper mHelper; - private View mNoRecentsView; - private Bitmap mLoadingBitmap; - private Bitmap mRecentOverlay; - private boolean mHidden = false; - private boolean mHiding = false; - private DetailInfo mDetailInfo; - - /** - * This class is a container for all items associated with the DetailView we'll - * be drawing to a bitmap and sending to Carousel. - * - */ - static final class DetailInfo { - public DetailInfo(View _view, TextView _title, TextView _desc) { - view = _view; - title = _title; - description = _desc; - } - - /** - * Draws view into the given bitmap, if provided - * @param bitmap - */ - public Bitmap draw(Bitmap bitmap) { - resizeView(view, DETAIL_TEXTURE_MAX_WIDTH, DETAIL_TEXTURE_MAX_HEIGHT); - int desiredWidth = view.getWidth(); - int desiredHeight = view.getHeight(); - if (bitmap == null || desiredWidth != bitmap.getWidth() - || desiredHeight != bitmap.getHeight()) { - bitmap = Bitmap.createBitmap(desiredWidth, desiredHeight, Config.ARGB_8888); - } - Canvas canvas = new Canvas(bitmap); - view.draw(canvas); - return bitmap; - } - - /** - * Force a layout pass on the given view. - */ - private void resizeView(View view, int maxWidth, int maxHeight) { - int widthSpec = MeasureSpec.getMode(MeasureSpec.AT_MOST) - | MeasureSpec.getSize(maxWidth); - int heightSpec = MeasureSpec.getMode(MeasureSpec.AT_MOST) - | MeasureSpec.getSize(maxHeight); - view.measure(widthSpec, heightSpec); - view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight()); - Log.v(TAG, "RESIZED VIEW: " + view.getWidth() + ", " + view.getHeight()); - } - - public View view; - public TextView title; - public TextView description; - } - - static class ActivityDescription { - int id; - Bitmap thumbnail; // generated by Activity.onCreateThumbnail() - Drawable icon; // application package icon - String label; // application package label - CharSequence description; // generated by Activity.onCreateDescription() - Intent intent; // launch intent for application - Matrix matrix; // arbitrary rotation matrix to correct orientation - int position; // position in list - - public ActivityDescription(Bitmap _thumbnail, - Drawable _icon, String _label, String _desc, int _id, int _pos) - { - thumbnail = _thumbnail; - icon = _icon; - label = _label; - description = _desc; - id = _id; - position = _pos; - } - - public void clear() { - icon = null; - thumbnail = null; - label = null; - description = null; - intent = null; - matrix = null; - id = -1; - position = -1; - } - }; - - private ActivityDescription findActivityDescription(int id) { - for (int i = 0; i < mActivityDescriptions.size(); i++) { - ActivityDescription item = mActivityDescriptions.get(i); - if (item != null && item.id == id) { - return item; - } - } - return null; - } - - private class LocalCarouselViewHelper extends CarouselViewHelper { - private DetailTextureParameters mDetailParams = new DetailTextureParameters(10.0f, 20.0f); - - public LocalCarouselViewHelper(Context context) { - super(context); - } - - @Override - public DetailTextureParameters getDetailTextureParameters(int id) { - return mDetailParams; - } - - public void onCardSelected(int n) { - if (n < mActivityDescriptions.size()) { - ActivityDescription item = mActivityDescriptions.get(n); - if (item.id >= 0) { - // This is an active task; it should just go to the foreground. - final ActivityManager am = (ActivityManager) - getSystemService(Context.ACTIVITY_SERVICE); - am.moveTaskToFront(item.id, ActivityManager.MOVE_TASK_WITH_HOME); - } else if (item.intent != null) { - // prepare a launch intent and send it - item.intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY - | Intent.FLAG_ACTIVITY_TASK_ON_HOME); - try { - if (DBG) Log.v(TAG, "Starting intent " + item.intent); - startActivity(item.intent); - overridePendingTransition(R.anim.recent_app_enter, R.anim.recent_app_leave); - } catch (ActivityNotFoundException e) { - if (DBG) Log.w("Recent", "Unable to launch recent task", e); - } - finish(); - } - } - } - - @Override - public Bitmap getTexture(final int id) { - if (DBG) Log.v(TAG, "onRequestTexture(" + id + ")"); - ActivityDescription info; - synchronized(mActivityDescriptions) { - info = mActivityDescriptions.get(id); - } - Bitmap bitmap = null; - if (info != null) { - bitmap = compositeBitmap(info); - } - return bitmap; - } - - @Override - public Bitmap getDetailTexture(int n) { - Bitmap bitmap = null; - if (n < mActivityDescriptions.size()) { - ActivityDescription item = mActivityDescriptions.get(n); - mDetailInfo.title.setText(item.label); - mDetailInfo.description.setText(item.description); - bitmap = mDetailInfo.draw(null); - } - return bitmap; - } - }; - - private Bitmap compositeBitmap(ActivityDescription info) { - final int targetWidth = TEXTURE_WIDTH; - final int targetHeight = TEXTURE_HEIGHT; - final int border = 3; // inset along the edge for thumnnail content - final int overlap = 1; // how many pixels of overlap between border and thumbnail - final Resources res = getResources(); - if (mRecentOverlay == null) { - mRecentOverlay = BitmapFactory.decodeResource(res, R.drawable.recent_overlay); - } - - // Create a bitmap of the proper size/format and set the canvas to draw to it - final Bitmap result = Bitmap.createBitmap(targetWidth, targetHeight, Bitmap.Config.ARGB_8888); - final Canvas canvas = new Canvas(result); - canvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG, Paint.FILTER_BITMAP_FLAG)); - Paint paint = new Paint(); - paint.setFilterBitmap(false); - - paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC)); - canvas.save(); - if (info.thumbnail != null) { - // Draw the thumbnail - int sourceWidth = targetWidth - 2 * (border - overlap); - int sourceHeight = targetHeight - 2 * (border - overlap); - final float scaleX = (float) sourceWidth / info.thumbnail.getWidth(); - final float scaleY = (float) sourceHeight / info.thumbnail.getHeight(); - canvas.translate(border * 0.5f, border * 0.5f); - canvas.scale(scaleX, scaleY); - canvas.drawBitmap(info.thumbnail, 0, 0, paint); - } else { - // Draw the Loading bitmap placeholder, TODO: Remove when RS handles blending - final float scaleX = (float) targetWidth / mLoadingBitmap.getWidth(); - final float scaleY = (float) targetHeight / mLoadingBitmap.getHeight(); - canvas.scale(scaleX, scaleY); - canvas.drawBitmap(mLoadingBitmap, 0, 0, paint); - } - canvas.restore(); - - // Draw overlay - canvas.save(); - final float scaleOverlayX = (float) targetWidth / mRecentOverlay.getWidth(); - final float scaleOverlayY = (float) targetHeight / mRecentOverlay.getHeight(); - canvas.scale(scaleOverlayX, scaleOverlayY); - paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.ADD)); - canvas.drawBitmap(mRecentOverlay, 0, 0, paint); - canvas.restore(); - - // Draw icon - if (info.icon != null) { - canvas.save(); - info.icon.draw(canvas); - canvas.restore(); - } - - return result; - } - - private final IThumbnailReceiver mThumbnailReceiver = new IThumbnailReceiver.Stub() { - - public void finished() throws RemoteException { - - } - - public void newThumbnail(final int id, final Bitmap bitmap, CharSequence description) - throws RemoteException { - int w = bitmap.getWidth(); - int h = bitmap.getHeight(); - if (DBG) Log.v(TAG, "New thumbnail for id=" + id + ", dimensions=" + w + "x" + h - + " description '" + description + "'"); - ActivityDescription info = findActivityDescription(id); - if (info != null) { - info.thumbnail = bitmap; - info.description = description; - final int thumbWidth = bitmap.getWidth(); - final int thumbHeight = bitmap.getHeight(); - if ((mPortraitMode && thumbWidth > thumbHeight) - || (!mPortraitMode && thumbWidth < thumbHeight)) { - Matrix matrix = new Matrix(); - matrix.setRotate(90.0f, (float) thumbWidth / 2, (float) thumbHeight / 2); - info.matrix = matrix; - } else { - info.matrix = null; - } - // Force Carousel to request new textures for this item. - mCarouselView.setTextureForItem(info.position, null); - mCarouselView.setDetailTextureForItem(info.position, 0, 0, 0, 0, null); - } else { - if (DBG) Log.v(TAG, "Can't find view for id " + id); - } - } - }; - - /** - * We never really finish() RecentApplicationsActivity, since we don't want to - * get destroyed and pay the start-up cost to restart it. - */ - @Override - public void finish() { - moveTaskToBack(true); - } - - @Override - protected void onNewIntent(Intent intent) { - mHidden = !mHidden; - if (mHidden) { - mHiding = true; - moveTaskToBack(true); - } else { - mHiding = false; - } - super.onNewIntent(intent); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - final Resources res = getResources(); - final View decorView = getWindow().getDecorView(); - - getWindow().getDecorView().setBackgroundColor(0x80000000); - - if (mCarouselView == null) { - long t = System.currentTimeMillis(); - setContentView(R.layout.recent_apps_activity); - long elapsed = System.currentTimeMillis() - t; - Log.v(TAG, "Recents layout took " + elapsed + "ms to load"); - mLoadingBitmap = BitmapFactory.decodeResource(res, R.drawable.recent_rez_border); - mCarouselView = (CarouselView)findViewById(R.id.carousel); - mHelper = new LocalCarouselViewHelper(this); - mHelper.setCarouselView(mCarouselView); - - mCarouselView.setSlotCount(CARD_SLOTS); - mCarouselView.setVisibleSlots(VISIBLE_SLOTS); - mCarouselView.createCards(0); - mCarouselView.setStartAngle((float) -(2.0f*Math.PI * 5 / CARD_SLOTS)); - mCarouselView.setDefaultBitmap(mLoadingBitmap); - mCarouselView.setLoadingBitmap(mLoadingBitmap); - mCarouselView.setRezInCardCount(3.0f); - mCarouselView.getHolder().setFormat(PixelFormat.TRANSLUCENT); - - mNoRecentsView = (View) findViewById(R.id.no_applications_message); - - mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); - mPortraitMode = decorView.getHeight() > decorView.getWidth(); - - // Load detail view which will be used to render text - View detail = getLayoutInflater().inflate(R.layout.recents_detail_view, null); - TextView title = (TextView) detail.findViewById(R.id.app_title); - TextView description = (TextView) detail.findViewById(R.id.app_description); - mDetailInfo = new DetailInfo(detail, title, description); - - refresh(); - } - } - - @Override - protected void onResume() { - super.onResume(); - refresh(); - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - mPortraitMode = newConfig.orientation == Configuration.ORIENTATION_PORTRAIT; - if (DBG) Log.v(TAG, "CONFIG CHANGE, mPortraitMode = " + mPortraitMode); - refresh(); - } - - void updateRunningTasks() { - mRunningTaskList = mActivityManager.getRunningTasks(MAX_TASKS, - 0, mThumbnailReceiver); - if (DBG) Log.v(TAG, "Portrait: " + mPortraitMode); - for (RunningTaskInfo r : mRunningTaskList) { - if (r.thumbnail != null) { - int thumbWidth = r.thumbnail.getWidth(); - int thumbHeight = r.thumbnail.getHeight(); - if (DBG) Log.v(TAG, "Got thumbnail " + thumbWidth + "x" + thumbHeight); - ActivityDescription desc = findActivityDescription(r.id); - if (desc != null) { - desc.thumbnail = r.thumbnail; - desc.description = r.description; - if ((mPortraitMode && thumbWidth > thumbHeight) - || (!mPortraitMode && thumbWidth < thumbHeight)) { - Matrix matrix = new Matrix(); - matrix.setRotate(90.0f, (float) thumbWidth / 2, (float) thumbHeight / 2); - desc.matrix = matrix; - } - } else { - if (DBG) Log.v(TAG, "Couldn't find ActivityDesc for id=" + r.id); - } - } else { - if (DBG) Log.v(TAG, "*** RUNNING THUMBNAIL WAS NULL ***"); - } - } - } - - private void updateRecentTasks() { - final PackageManager pm = getPackageManager(); - final ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); - - final List<ActivityManager.RecentTaskInfo> recentTasks = - am.getRecentTasks(MAX_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE); - - ActivityInfo homeInfo = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME) - .resolveActivityInfo(pm, 0); - - // IconUtilities iconUtilities = new IconUtilities(this); // FIXME - - int numTasks = recentTasks.size(); - mActivityDescriptions.clear(); - for (int i = 0, index = 0; i < numTasks && (index < MAX_TASKS); ++i) { - final ActivityManager.RecentTaskInfo recentInfo = recentTasks.get(i); - - Intent intent = new Intent(recentInfo.baseIntent); - if (recentInfo.origActivity != null) { - intent.setComponent(recentInfo.origActivity); - } - - // Skip the current home activity. - if (homeInfo != null - && homeInfo.packageName.equals(intent.getComponent().getPackageName()) - && homeInfo.name.equals(intent.getComponent().getClassName())) { - continue; - } - - intent.setFlags((intent.getFlags()&~Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) - | Intent.FLAG_ACTIVITY_NEW_TASK); - final ResolveInfo resolveInfo = pm.resolveActivity(intent, 0); - if (resolveInfo != null) { - final ActivityInfo info = resolveInfo.activityInfo; - final String title = info.loadLabel(pm).toString(); - Drawable icon = info.loadIcon(pm); - - int id = recentTasks.get(i).id; - if (id != -1 && title != null && title.length() > 0 && icon != null) { - // icon = null; FIXME: iconUtilities.createIconDrawable(icon); - ActivityDescription item = new ActivityDescription( - null, icon, title, null, id, index); - item.intent = intent; - mActivityDescriptions.add(item); - if (DBG) Log.v(TAG, "Added item[" + index - + "], id=" + item.id - + ", title=" + item.label); - ++index; - } else { - if (DBG) Log.v(TAG, "SKIPPING item " + id); - } - } - } - } - - private final Runnable mRefreshRunnable = new Runnable() { - public void run() { - updateRecentTasks(); - updateRunningTasks(); - showCarousel(mActivityDescriptions.size() > 0); - } - }; - - private void showCarousel(boolean show) { - if (show) { - mCarouselView.createCards(mActivityDescriptions.size()); - for (int i = 1; i < mActivityDescriptions.size(); i++) { - // Force Carousel to update textures. Note we don't do this for the first item, - // since it will be updated when mThumbnailReceiver returns a thumbnail. - // TODO: only do this for apps that have changed. - mCarouselView.setTextureForItem(i, null); - mCarouselView.setDetailTextureForItem(i, 0, 0, 0, 0, null); - } - // Make carousel visible - mNoRecentsView.setVisibility(View.GONE); - mCarouselView.setVisibility(View.VISIBLE); - mCarouselView.createCards(mActivityDescriptions.size()); - } else { - // show "No Recent Tasks" - mNoRecentsView.setVisibility(View.VISIBLE); - mCarouselView.setVisibility(View.GONE); - } - } - - private void refresh() { - if (!mHiding && mCarouselView != null) { - // Don't update the view now. Instead, post a request so it happens next time - // we reach the looper after a delay. This way we can fold multiple refreshes - // into just the latest. - mCarouselView.removeCallbacks(mRefreshRunnable); - mCarouselView.postDelayed(mRefreshRunnable, 50); - } - } -} diff --git a/packages/SystemUI/src/com/android/systemui/recent/carousel/RecentApplicationsCarouselView.java b/packages/SystemUI/src/com/android/systemui/recent/carousel/RecentApplicationsCarouselView.java deleted file mode 100644 index 1afb086..0000000 --- a/packages/SystemUI/src/com/android/systemui/recent/carousel/RecentApplicationsCarouselView.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.recent.carousel; - -import android.content.Context; -import android.util.AttributeSet; - -import com.android.ex.carousel.CarouselView; -import com.android.systemui.R; - -public class RecentApplicationsCarouselView extends CarouselView { - - public RecentApplicationsCarouselView(Context context) { - this(context, null); - } - - public RecentApplicationsCarouselView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public Info getRenderScriptInfo() { - return new Info(R.raw.carousel); - } - -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java index f81820e..62d7500 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java @@ -61,6 +61,7 @@ public class CommandQueue extends IStatusBar.Stub { private static final int MSG_SET_HARD_KEYBOARD_STATUS = 10 << MSG_SHIFT; private static final int MSG_USER_ACTIVITY = 11 << MSG_SHIFT; + private static final int MSG_TOGGLE_RECENT_APPS = 12 << MSG_SHIFT; private StatusBarIconList mList; private Callbacks mCallbacks; @@ -90,6 +91,7 @@ public class CommandQueue extends IStatusBar.Stub { public void setImeWindowStatus(IBinder token, int vis, int backDisposition); public void setHardKeyboardStatus(boolean available, boolean enabled); public void userActivity(); + public void toggleRecentApps(); } public CommandQueue(Callbacks callbacks, StatusBarIconList list) { @@ -196,6 +198,13 @@ public class CommandQueue extends IStatusBar.Stub { } } + public void toggleRecentApps() { + synchronized (mList) { + mHandler.removeMessages(MSG_TOGGLE_RECENT_APPS); + mHandler.obtainMessage(MSG_TOGGLE_RECENT_APPS, 0, 0, null).sendToTarget(); + } + } + private final class H extends Handler { public void handleMessage(Message msg) { final int what = msg.what & MSG_MASK; @@ -265,6 +274,9 @@ public class CommandQueue extends IStatusBar.Stub { case MSG_USER_ACTIVITY: mCallbacks.userActivity(); break; + case MSG_TOGGLE_RECENT_APPS: + mCallbacks.toggleRecentApps(); + break; } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java index e567dc7..ca75138 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java @@ -53,6 +53,7 @@ public abstract class StatusBar extends SystemUI implements CommandQueue.Callbac protected abstract View makeStatusBarView(); protected abstract int getStatusBarGravity(); public abstract int getStatusBarHeight(); + public abstract void animateCollapse(); private DoNotDisturb mDoNotDisturb; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index cc8358e..0b82123 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -28,10 +28,12 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.Resources; +import android.content.res.Configuration; import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.net.Uri; +import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.os.Handler; @@ -74,6 +76,7 @@ import com.android.internal.statusbar.StatusBarIconList; import com.android.internal.statusbar.StatusBarNotification; import com.android.systemui.R; +import com.android.systemui.recent.RecentsPanelView; import com.android.systemui.statusbar.NotificationData; import com.android.systemui.statusbar.StatusBar; import com.android.systemui.statusbar.StatusBarIconView; @@ -83,6 +86,7 @@ import com.android.systemui.statusbar.policy.DateView; public class PhoneStatusBar extends StatusBar { static final String TAG = "PhoneStatusBar"; static final boolean SPEW = false; + public static final boolean DEBUG = false; public static final String ACTION_STATUSBAR_START = "com.android.internal.policy.statusbar.START"; @@ -94,6 +98,8 @@ public class PhoneStatusBar extends StatusBar { private static final int MSG_ANIMATE_REVEAL = 1001; private static final int MSG_SHOW_INTRUDER = 1002; private static final int MSG_HIDE_INTRUDER = 1003; + private static final int MSG_OPEN_RECENTS_PANEL = 1020; + private static final int MSG_CLOSE_RECENTS_PANEL = 1021; // will likely move to a resource or other tunable param at some point private static final int INTRUDER_ALERT_DECAY_MS = 10000; @@ -160,6 +166,9 @@ public class PhoneStatusBar extends StatusBar { private View mTickerView; private boolean mTicking; + // Recent applications + private RecentsPanelView mRecentsPanel; + // Tracking finger for opening/closing. int mEdgeBorder; // corresponds to R.dimen.status_bar_edge_ignore boolean mTracking; @@ -296,6 +305,9 @@ public class PhoneStatusBar extends StatusBar { setAreThereNotifications(); mDateView.setVisibility(View.INVISIBLE); + // Recents Panel + initializeRecentsPanel(); + // receive broadcasts IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); @@ -306,6 +318,51 @@ public class PhoneStatusBar extends StatusBar { return sb; } + protected WindowManager.LayoutParams getRecentsLayoutParams() { + boolean translucent = false; + WindowManager.LayoutParams lp = new WindowManager.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT, + WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, + WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN + | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM + | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH + | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, + (translucent ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT)); + lp.gravity = Gravity.BOTTOM | Gravity.LEFT; + lp.setTitle("RecentsPanel"); + lp.windowAnimations = R.style.Animation_RecentPanel; + lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED + | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; + return lp; + } + + protected void initializeRecentsPanel() { + // Recents Panel + boolean visible = false; + if (mRecentsPanel != null) { + visible = mRecentsPanel.getVisibility() == View.VISIBLE; + WindowManagerImpl.getDefault().removeView(mRecentsPanel); + } + mRecentsPanel = (RecentsPanelView) View.inflate(mContext, + R.layout.status_bar_recent_panel, null); + + mRecentsPanel.setOnTouchListener(new TouchOutsideListener(MSG_CLOSE_RECENTS_PANEL, + mRecentsPanel)); + mRecentsPanel.setVisibility(View.GONE); + WindowManager.LayoutParams lp = getRecentsLayoutParams(); + + WindowManagerImpl.getDefault().addView(mRecentsPanel, lp); + mRecentsPanel.setBar(this); + if (visible) { + // need to set visibility to View.GONE earlier since that + // triggers refreshing application list + mRecentsPanel.setVisibility(View.VISIBLE); + mRecentsPanel.show(true, false); + } + + } + protected int getStatusBarGravity() { return Gravity.TOP | Gravity.FILL_HORIZONTAL; } @@ -581,6 +638,12 @@ public class PhoneStatusBar extends StatusBar { } } + @Override + protected void onConfigurationChanged(Configuration newConfig) { + initializeRecentsPanel(); + } + + View[] makeNotificationView(StatusBarNotification notification, ViewGroup parent) { Notification n = notification.notification; RemoteViews remoteViews = n.contentView; @@ -789,6 +852,21 @@ public class PhoneStatusBar extends StatusBar { case MSG_HIDE_INTRUDER: setIntruderAlertVisibility(false); break; + case MSG_OPEN_RECENTS_PANEL: + if (DEBUG) Slog.d(TAG, "opening recents panel"); + if (mRecentsPanel != null) { + disable(StatusBarManager.DISABLE_BACK); + mRecentsPanel.setVisibility(View.VISIBLE); + mRecentsPanel.show(true, true); + } + break; + case MSG_CLOSE_RECENTS_PANEL: + if (DEBUG) Slog.d(TAG, "closing recents panel"); + if (mRecentsPanel != null && mRecentsPanel.isShowing()) { + disable(StatusBarManager.DISABLE_NONE); + mRecentsPanel.show(false, true); + } + break; } } } @@ -835,6 +913,10 @@ public class PhoneStatusBar extends StatusBar { } public void animateCollapse() { + animateCollapse(false); + } + + public void animateCollapse(boolean excludeRecents) { if (SPEW) { Slog.d(TAG, "animateCollapse(): mExpanded=" + mExpanded + " mExpandedVisible=" + mExpandedVisible @@ -844,6 +926,11 @@ public class PhoneStatusBar extends StatusBar { + " mAnimVel=" + mAnimVel); } + if (!excludeRecents) { + mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL); + mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL); + } + if (!mExpandedVisible) { return; } @@ -1557,6 +1644,13 @@ public class PhoneStatusBar extends StatusBar { } catch (RemoteException ex) { } } + public void toggleRecentApps() { + int msg = (mRecentsPanel.getVisibility() == View.GONE) + ? MSG_OPEN_RECENTS_PANEL : MSG_CLOSE_RECENTS_PANEL; + mHandler.removeMessages(msg); + mHandler.sendEmptyMessage(msg); + } + /** * The LEDs are turned o)ff when the notification panel is shown, even just a little bit. * This was added last-minute and is inconsistent with the way the rest of the notifications @@ -1625,7 +1719,14 @@ public class PhoneStatusBar extends StatusBar { String action = intent.getAction(); if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action) || Intent.ACTION_SCREEN_OFF.equals(action)) { - animateCollapse(); + boolean excludeRecents = false; + if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) { + String reason = intent.getExtras().getString("reason"); + if (reason != null) { + excludeRecents = reason.equals("recentapps"); + } + } + animateCollapse(excludeRecents); } else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) { repositionNavigationBar(); @@ -1690,5 +1791,27 @@ public class PhoneStatusBar extends StatusBar { vibrate(); } }; + + public class TouchOutsideListener implements View.OnTouchListener { + private int mMsg; + private RecentsPanelView mPanel; + + public TouchOutsideListener(int msg, RecentsPanelView panel) { + mMsg = msg; + mPanel = panel; + } + + public boolean onTouch(View v, MotionEvent ev) { + final int action = ev.getAction(); + if (action == MotionEvent.ACTION_OUTSIDE + || (action == MotionEvent.ACTION_DOWN + && !mPanel.isInContentArea((int)ev.getX(), (int)ev.getY()))) { + mHandler.removeMessages(mMsg); + mHandler.sendEmptyMessage(mMsg); + return true; + } + return false; + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/CompatModePanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/CompatModePanel.java index 5a82d1b..c62c4ad 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/CompatModePanel.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/CompatModePanel.java @@ -107,9 +107,14 @@ public class CompatModePanel extends FrameLayout implements StatusBarPanel, private void refresh() { int mode = mAM.getFrontActivityScreenCompatMode(); + if (mode == ActivityManager.COMPAT_MODE_ALWAYS + || mode == ActivityManager.COMPAT_MODE_NEVER) { + // No longer have something to switch. + closePanel(); + return; + } final boolean on = (mode == ActivityManager.COMPAT_MODE_ENABLED); mOnButton.setChecked(on); mOffButton.setChecked(!on); } - } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java index a7af30d..93f7af3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java @@ -76,12 +76,12 @@ import com.android.systemui.statusbar.policy.LocationController; import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.statusbar.policy.Prefs; import com.android.systemui.recent.RecentsPanelView; -import com.android.systemui.recent.carousel.RecentApplicationsActivity; public class TabletStatusBar extends StatusBar implements HeightReceiver.OnBarHeightChangedListener, InputMethodsPanel.OnHardKeyboardEnabledChangeListener { public static final boolean DEBUG = false; + public static final boolean DEBUG_COMPAT_HELP = false; public static final String TAG = "TabletStatusBar"; @@ -166,6 +166,8 @@ public class TabletStatusBar extends StatusBar implements View mFakeSpaceBar; KeyEvent mSpaceBarKeyEvent = null; + View mCompatibilityHelpDialog = null; + // for disabling the status bar int mDisabled = 0; @@ -1010,20 +1012,31 @@ public class TabletStatusBar extends StatusBar implements mCompatModeButton.refresh(); if (mCompatModeButton.getVisibility() == View.VISIBLE) { - if (! Prefs.read(mContext).getBoolean(Prefs.SHOWN_COMPAT_MODE_HELP, false)) { + if (DEBUG_COMPAT_HELP + || ! Prefs.read(mContext).getBoolean(Prefs.SHOWN_COMPAT_MODE_HELP, false)) { showCompatibilityHelp(); } + } else { + hideCompatibilityHelp(); + mCompatModePanel.closePanel(); } } private void showCompatibilityHelp() { - final View dlg = View.inflate(mContext, R.layout.compat_mode_help, null); - View button = dlg.findViewById(R.id.button); + if (mCompatibilityHelpDialog != null) { + return; + } + + mCompatibilityHelpDialog = View.inflate(mContext, R.layout.compat_mode_help, null); + View button = mCompatibilityHelpDialog.findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - WindowManagerImpl.getDefault().removeView(dlg); + hideCompatibilityHelp(); + SharedPreferences.Editor editor = Prefs.edit(mContext); + editor.putBoolean(Prefs.SHOWN_COMPAT_MODE_HELP, true); + editor.apply(); } }); @@ -1040,13 +1053,16 @@ public class TabletStatusBar extends StatusBar implements | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; lp.windowAnimations = com.android.internal.R.style.Animation_ZoomButtons; // simple fade - WindowManagerImpl.getDefault().addView(dlg, lp); - - SharedPreferences.Editor editor = Prefs.edit(mContext); - editor.putBoolean(Prefs.SHOWN_COMPAT_MODE_HELP, true); - editor.apply(); + WindowManagerImpl.getDefault().addView(mCompatibilityHelpDialog, lp); } + private void hideCompatibilityHelp() { + if (mCompatibilityHelpDialog != null) { + WindowManagerImpl.getDefault().removeView(mCompatibilityHelpDialog); + mCompatibilityHelpDialog = null; + } + } + public void setImeWindowStatus(IBinder token, int vis, int backDisposition) { mInputMethodSwitchButton.setImeWindowStatus(token, (vis & InputMethodService.IME_ACTIVE) != 0); @@ -1156,20 +1172,12 @@ public class TabletStatusBar extends StatusBar implements public void onClickRecentButton() { if (DEBUG) Slog.d(TAG, "clicked recent apps; disabled=" + mDisabled); - if (mRecentsPanel == null) { - Intent intent = new Intent(); - intent.setClass(mContext, RecentApplicationsActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK - | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); - mContext.startActivity(intent); - } else { - if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) { - int msg = (mRecentsPanel.getVisibility() == View.GONE) - ? MSG_OPEN_RECENTS_PANEL - : MSG_CLOSE_RECENTS_PANEL; - mHandler.removeMessages(msg); - mHandler.sendEmptyMessage(msg); - } + if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) { + int msg = (mRecentsPanel.getVisibility() == View.GONE) + ? MSG_OPEN_RECENTS_PANEL + : MSG_CLOSE_RECENTS_PANEL; + mHandler.removeMessages(msg); + mHandler.sendEmptyMessage(msg); } } @@ -1681,6 +1689,13 @@ public class TabletStatusBar extends StatusBar implements public void userActivity() { } + public void toggleRecentApps() { + int msg = (mRecentsPanel.getVisibility() == View.GONE) + ? MSG_OPEN_RECENTS_PANEL : MSG_CLOSE_RECENTS_PANEL; + mHandler.removeMessages(msg); + mHandler.sendEmptyMessage(msg); + } + public class TouchOutsideListener implements View.OnTouchListener { private int mMsg; private StatusBarPanel mPanel; diff --git a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java index 72209f6..f385a23 100644 --- a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java +++ b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java @@ -114,7 +114,15 @@ public class KeyguardUpdateMonitor { } String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE); if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) { - this.simState = IccCard.State.ABSENT; + final String absentReason = intent + .getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON); + + if (IccCard.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals( + absentReason)) { + this.simState = IccCard.State.PERM_DISABLED; + } else { + this.simState = IccCard.State.ABSENT; + } } else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) { this.simState = IccCard.State.READY; } else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) { diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java index 8a60098..8ba235b 100644 --- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java +++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java @@ -580,7 +580,9 @@ public class KeyguardViewMediator implements KeyguardViewCallback, final boolean provisioned = mUpdateMonitor.isDeviceProvisioned(); final IccCard.State state = mUpdateMonitor.getSimState(); final boolean lockedOrMissing = state.isPinLocked() - || ((state == IccCard.State.ABSENT) && requireSim); + || ((state == IccCard.State.ABSENT + || state == IccCard.State.PERM_DISABLED) + && requireSim); if (!lockedOrMissing && !provisioned) { if (DEBUG) Log.d(TAG, "doKeyguard: not showing because device isn't provisioned" @@ -687,12 +689,15 @@ public class KeyguardViewMediator implements KeyguardViewCallback, switch (simState) { case ABSENT: + case PERM_DISABLED: // only force lock screen in case of missing sim if user hasn't // gone through setup wizard if (!mUpdateMonitor.isDeviceProvisioned()) { if (!isShowing()) { - if (DEBUG) Log.d(TAG, "INTENT_VALUE_ICC_ABSENT and keygaurd isn't showing, we need " - + "to show the keyguard since the device isn't provisioned yet."); + if (DEBUG) Log.d(TAG, "INTENT_VALUE_ICC_ABSENT " + + "or PERM_DISABLED and keygaurd isn't showing," + + " we need to show the keyguard since the " + + "device isn't provisioned yet."); doKeyguard(); } else { resetStateLocked(); diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java index 874acd0..eea3040 100644 --- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java +++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java @@ -181,7 +181,8 @@ public class LockPatternKeyguardView extends KeyguardViewBase { private boolean stuckOnLockScreenBecauseSimMissing() { return mRequiresSim && (!mUpdateMonitor.isDeviceProvisioned()) - && (mUpdateMonitor.getSimState() == IccCard.State.ABSENT); + && (mUpdateMonitor.getSimState() == IccCard.State.ABSENT || + mUpdateMonitor.getSimState() == IccCard.State.PERM_DISABLED); } /** diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java index ed5a058..19adb3e 100644 --- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java +++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java @@ -55,8 +55,10 @@ public class LockPatternKeyguardViewProperties implements KeyguardViewProperties private boolean isSimPinSecure() { final IccCard.State simState = mUpdateMonitor.getSimState(); - return (simState == IccCard.State.PIN_REQUIRED || simState == IccCard.State.PUK_REQUIRED - || simState == IccCard.State.ABSENT); + return (simState == IccCard.State.PIN_REQUIRED + || simState == IccCard.State.PUK_REQUIRED + || simState == IccCard.State.ABSENT + || simState == IccCard.State.PERM_DISABLED); } } diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java index 08f9ebb..8b7a61e 100644 --- a/policy/src/com/android/internal/policy/impl/LockScreen.java +++ b/policy/src/com/android/internal/policy/impl/LockScreen.java @@ -129,7 +129,12 @@ class LockScreen extends LinearLayout implements KeyguardScreen, /** * The sim card is locked. */ - SimLocked(true); + SimLocked(true), + + /** + * The sim card is permanently disabled due to puk unlock failure + */ + SimPermDisabled(false); private final boolean mShowStatusLines; @@ -503,7 +508,9 @@ class LockScreen extends LinearLayout implements KeyguardScreen, */ private Status getCurrentStatus(IccCard.State simState) { boolean missingAndNotProvisioned = (!mUpdateMonitor.isDeviceProvisioned() - && simState == IccCard.State.ABSENT); + && (simState == IccCard.State.ABSENT + || simState == IccCard.State.PERM_DISABLED)); + if (missingAndNotProvisioned) { return Status.SimMissingLocked; } @@ -521,6 +528,8 @@ class LockScreen extends LinearLayout implements KeyguardScreen, return Status.SimPukLocked; case READY: return Status.Normal; + case PERM_DISABLED: + return Status.SimPermDisabled; case UNKNOWN: return Status.SimMissing; } @@ -595,6 +604,18 @@ class LockScreen extends LinearLayout implements KeyguardScreen, enableUnlock(); // do not need to show the e-call button; user may unlock break; + case SimPermDisabled: + // text + mStatusView.setCarrierText(R.string.lockscreen_missing_sim_message_short); + mScreenLocked.setText( + R.string.lockscreen_permanent_disabled_sim_instructions); + + // layout + mScreenLocked.setVisibility(View.VISIBLE); + mLockPatternUtils.updateEmergencyCallText(mEmergencyCallText); + enableUnlock(); // do not need to show the e-call button; user may unlock + break; + case SimMissingLocked: // text mStatusView.setCarrierText( diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 5728989..b52e7e1 100755 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -149,10 +149,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { static final int LONG_PRESS_POWER_NOTHING = 0; static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1; static final int LONG_PRESS_POWER_SHUT_OFF = 2; - + + // These need to match the documentation/constant in + // core/res/res/values/config.xml static final int LONG_PRESS_HOME_NOTHING = 0; static final int LONG_PRESS_HOME_RECENT_DIALOG = 1; - static final int LONG_PRESS_HOME_RECENT_ACTIVITY = 2; + static final int LONG_PRESS_HOME_RECENT_SYSTEM_UI = 2; // wallpaper is at the bottom, though the window manager may move it. static final int WALLPAPER_LAYER = 2; @@ -623,7 +625,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { mLongPressOnHomeBehavior = mContext.getResources().getInteger(R.integer.config_longPressOnHomeBehavior); if (mLongPressOnHomeBehavior < LONG_PRESS_HOME_NOTHING || - mLongPressOnHomeBehavior > LONG_PRESS_HOME_RECENT_ACTIVITY) { + mLongPressOnHomeBehavior > LONG_PRESS_HOME_RECENT_SYSTEM_UI) { mLongPressOnHomeBehavior = LONG_PRESS_HOME_NOTHING; } } @@ -639,17 +641,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_DIALOG) { showOrHideRecentAppsDialog(0, true /*dismissIfShown*/); - } else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_ACTIVITY) { + } else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_SYSTEM_UI) { try { - Intent intent = new Intent(); - intent.setClassName("com.android.systemui", - "com.android.systemui.recent.RecentApplicationsActivity"); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK - | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); - mContext.startActivity(intent); - return; - } catch (ActivityNotFoundException e) { - Log.e(TAG, "Failed to launch RecentAppsIntent", e); + mStatusBarService.toggleRecentApps(); + } catch (RemoteException e) { + Slog.e(TAG, "RemoteException when showing recent apps", e); } } } diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index 1e8c30b..a011ae2 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -147,6 +147,14 @@ sp<ICamera> CameraService::connect( return NULL; } + char value[PROPERTY_VALUE_MAX]; + property_get("sys.secpolicy.camera.disabled", value, "0"); + if (strcmp(value, "1") == 0) { + // Camera is disabled by DevicePolicyManager. + LOGI("Camera is disabled. connect X (pid %d) rejected", callingPid); + return NULL; + } + Mutex::Autolock lock(mServiceLock); if (mClient[cameraId] != 0) { client = mClient[cameraId].promote(); diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java index fd502d8..158c778 100644 --- a/services/java/com/android/server/AppWidgetService.java +++ b/services/java/com/android/server/AppWidgetService.java @@ -395,41 +395,47 @@ class AppWidgetService extends IAppWidgetService.Stub public void bindAppWidgetId(int appWidgetId, ComponentName provider) { mContext.enforceCallingPermission(android.Manifest.permission.BIND_APPWIDGET, "bindGagetId appWidgetId=" + appWidgetId + " provider=" + provider); - synchronized (mAppWidgetIds) { - AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId); - if (id == null) { - throw new IllegalArgumentException("bad appWidgetId"); - } - if (id.provider != null) { - throw new IllegalArgumentException("appWidgetId " + appWidgetId + " already bound to " - + id.provider.info.provider); - } - Provider p = lookupProviderLocked(provider); - if (p == null) { - throw new IllegalArgumentException("not a appwidget provider: " + provider); - } - if (p.zombie) { - throw new IllegalArgumentException("can't bind to a 3rd party provider in" - + " safe mode: " + provider); - } - - id.provider = p; - p.instances.add(id); - int instancesSize = p.instances.size(); - if (instancesSize == 1) { - // tell the provider that it's ready - sendEnableIntentLocked(p); + + final long ident = Binder.clearCallingIdentity(); + try { + synchronized (mAppWidgetIds) { + AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId); + if (id == null) { + throw new IllegalArgumentException("bad appWidgetId"); + } + if (id.provider != null) { + throw new IllegalArgumentException("appWidgetId " + appWidgetId + " already bound to " + + id.provider.info.provider); + } + Provider p = lookupProviderLocked(provider); + if (p == null) { + throw new IllegalArgumentException("not a appwidget provider: " + provider); + } + if (p.zombie) { + throw new IllegalArgumentException("can't bind to a 3rd party provider in" + + " safe mode: " + provider); + } + + id.provider = p; + p.instances.add(id); + int instancesSize = p.instances.size(); + if (instancesSize == 1) { + // tell the provider that it's ready + sendEnableIntentLocked(p); + } + + // send an update now -- We need this update now, and just for this appWidgetId. + // It's less critical when the next one happens, so when we schdule the next one, + // we add updatePeriodMillis to its start time. That time will have some slop, + // but that's okay. + sendUpdateIntentLocked(p, new int[] { appWidgetId }); + + // schedule the future updates + registerForBroadcastsLocked(p, getAppWidgetIds(p)); + saveStateLocked(); } - - // send an update now -- We need this update now, and just for this appWidgetId. - // It's less critical when the next one happens, so when we schdule the next one, - // we add updatePeriodMillis to its start time. That time will have some slop, - // but that's okay. - sendUpdateIntentLocked(p, new int[] { appWidgetId }); - - // schedule the future updates - registerForBroadcastsLocked(p, getAppWidgetIds(p)); - saveStateLocked(); + } finally { + Binder.restoreCallingIdentity(ident); } } diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index 385448f..07855d9 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -16,8 +16,7 @@ package com.android.server; -import static android.Manifest.permission.READ_PHONE_STATE; -import static android.Manifest.permission.UPDATE_DEVICE_STATS; +import static android.Manifest.permission.MANAGE_NETWORK_POLICY; import static android.net.ConnectivityManager.isNetworkTypeValid; import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; import static android.net.NetworkPolicyManager.RULE_REJECT_PAID; @@ -1142,8 +1141,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { @Override public void onRulesChanged(int uid, int uidRules) { // only someone like NPMS should only be calling us - // TODO: create permission for modifying data policy - mContext.enforceCallingOrSelfPermission(UPDATE_DEVICE_STATS, TAG); + mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); if (LOGD_RULES) { Slog.d(TAG, "onRulesChanged(uid=" + uid + ", uidRules=" + uidRules + ")"); @@ -1267,8 +1265,30 @@ public class ConnectivityService extends IConnectivityManager.Stub { } } intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished); + + // Reset interface if no other connections are using the same interface + boolean doReset = true; + LinkProperties linkProperties = mNetTrackers[prevNetType].getLinkProperties(); + if (linkProperties != null) { + String oldIface = linkProperties.getInterfaceName(); + if (TextUtils.isEmpty(oldIface) == false) { + for (NetworkStateTracker networkStateTracker : mNetTrackers) { + if (networkStateTracker == null) continue; + NetworkInfo networkInfo = networkStateTracker.getNetworkInfo(); + if (networkInfo.isConnected() && networkInfo.getType() != prevNetType) { + LinkProperties l = networkStateTracker.getLinkProperties(); + if (l == null) continue; + if (oldIface.equals(l.getInterfaceName())) { + doReset = false; + break; + } + } + } + } + } + // do this before we broadcast the change - handleConnectivityChange(prevNetType); + handleConnectivityChange(prevNetType, doReset); sendStickyBroadcast(intent); /* @@ -1490,7 +1510,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { } thisNet.setTeardownRequested(false); updateNetworkSettings(thisNet); - handleConnectivityChange(type); + handleConnectivityChange(type, false); sendConnectedBroadcast(info); } @@ -1500,7 +1520,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { * according to which networks are connected, and ensuring that the * right routing table entries exist. */ - private void handleConnectivityChange(int netType) { + private void handleConnectivityChange(int netType, boolean doReset) { /* * If a non-default network is enabled, add the host routes that * will allow it's DNS servers to be accessed. @@ -1540,6 +1560,17 @@ public class ConnectivityService extends IConnectivityManager.Stub { removePrivateDnsRoutes(mNetTrackers[netType]); } } + + if (doReset) { + LinkProperties linkProperties = mNetTrackers[netType].getLinkProperties(); + if (linkProperties != null) { + String iface = linkProperties.getInterfaceName(); + if (TextUtils.isEmpty(iface) == false) { + if (DBG) log("resetConnections(" + iface + ")"); + NetworkUtils.resetConnections(iface); + } + } + } } private void addPrivateDnsRoutes(NetworkStateTracker nt) { @@ -1965,7 +1996,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { break; case NetworkStateTracker.EVENT_CONFIGURATION_CHANGED: info = (NetworkInfo) msg.obj; - handleConnectivityChange(info.getType()); + handleConnectivityChange(info.getType(), true); break; case EVENT_CLEAR_NET_TRANSITION_WAKELOCK: String causedBy = null; diff --git a/services/java/com/android/server/StatusBarManagerService.java b/services/java/com/android/server/StatusBarManagerService.java index b1bce50..286a937 100644 --- a/services/java/com/android/server/StatusBarManagerService.java +++ b/services/java/com/android/server/StatusBarManagerService.java @@ -345,6 +345,15 @@ public class StatusBarManagerService extends IStatusBarService.Stub }); } + @Override + public void toggleRecentApps() { + if (mBar != null) { + try { + mBar.toggleRecentApps(); + } catch (RemoteException ex) {} + } + } + private void enforceStatusBar() { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR, "StatusBarManagerService"); diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java index ec59da6..a9dfb22 100644 --- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -441,6 +441,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub if (oldService != null) { tryRemoveServiceLocked(oldService); } + // This API is intended for testing so enable accessibility to make + // sure clients can start poking with the window content. + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_ENABLED, 1); + // Also disable all accessibility services to avoid interference + // with the tests. + Settings.Secure.putString(mContext.getContentResolver(), + Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, ""); } AccessibilityServiceInfo accessibilityServiceInfo = new AccessibilityServiceInfo(); accessibilityServiceInfo.eventTypes = AccessibilityEvent.TYPES_ALL_MASK; diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java index dac0044..9cbe82d 100644 --- a/services/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java @@ -747,6 +747,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { @Override public void registerListener(INetworkPolicyListener listener) { + // TODO: create permission for observing network policy + mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); + mListeners.register(listener); synchronized (mRulesLock) { @@ -767,6 +770,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { @Override public void unregisterListener(INetworkPolicyListener listener) { + // TODO: create permission for observing network policy + mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); + mListeners.unregister(listener); } diff --git a/services/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/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java index 476aded..edccf6c 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java @@ -25,13 +25,16 @@ import static android.net.NetworkPolicyManager.RULE_REJECT_PAID; import static android.net.NetworkPolicyManager.computeLastCycleBoundary; import static android.net.NetworkStats.UID_ALL; import static android.net.TrafficStats.TEMPLATE_WIFI; +import static org.easymock.EasyMock.anyInt; import static org.easymock.EasyMock.capture; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.eq; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.expectLastCall; +import static org.easymock.EasyMock.isA; import android.app.IActivityManager; +import android.app.INotificationManager; import android.app.IProcessObserver; import android.content.Intent; import android.content.pm.PackageManager; @@ -81,14 +84,15 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { private INetworkPolicyListener mPolicyListener; private TrustedTime mTime; private IConnectivityManager mConnManager; + private INotificationManager mNotifManager; private NetworkPolicyManagerService mService; private IProcessObserver mProcessObserver; private Binder mStubBinder = new Binder(); - private static final int UID_A = 800; - private static final int UID_B = 801; + private static final int UID_A = android.os.Process.FIRST_APPLICATION_UID + 800; + private static final int UID_B = android.os.Process.FIRST_APPLICATION_UID + 801; private static final int PID_1 = 400; private static final int PID_2 = 401; @@ -119,10 +123,12 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { mPolicyListener = createMock(INetworkPolicyListener.class); mTime = createMock(TrustedTime.class); mConnManager = createMock(IConnectivityManager.class); + mNotifManager = createMock(INotificationManager.class); mService = new NetworkPolicyManagerService( mServiceContext, mActivityManager, mPowerManager, mStatsService, mTime, mPolicyDir); mService.bindConnectivityManager(mConnManager); + mService.bindNotificationManager(mNotifManager); // RemoteCallbackList needs a binder to use as key expect(mPolicyListener.asBinder()).andReturn(mStubBinder).atLeastOnce(); @@ -137,6 +143,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { // expect to answer screen status during systemReady() expect(mPowerManager.isScreenOn()).andReturn(true).atLeastOnce(); + expectTime(System.currentTimeMillis()); replay(); mService.systemReady(); @@ -365,6 +372,8 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { // expect that quota remaining should be 1536 bytes // TODO: write up NetworkManagementService mock + expectClearNotifications(); + replay(); setNetworkPolicies(new NetworkPolicy(TEMPLATE_WIFI, null, CYCLE_DAY, 1024L, 2048L)); verifyAndReset(); @@ -388,7 +397,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { return new NetworkState(info, prop, null); } - public void expectTime(long currentTime) throws Exception { + private void expectTime(long currentTime) throws Exception { expect(mTime.forceRefresh()).andReturn(false).anyTimes(); expect(mTime.hasCache()).andReturn(true).anyTimes(); expect(mTime.currentTimeMillis()).andReturn(currentTime).anyTimes(); @@ -396,6 +405,11 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { expect(mTime.getCacheCertainty()).andReturn(0L).anyTimes(); } + private void expectClearNotifications() throws Exception { + mNotifManager.cancelNotificationWithTag(isA(String.class), isA(String.class), anyInt()); + expectLastCall().anyTimes(); + } + private void expectRulesChanged(int uid, int policy) throws Exception { mPolicyListener.onRulesChanged(eq(uid), eq(policy)); expectLastCall().atLeastOnce(); @@ -403,13 +417,13 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { private void replay() { EasyMock.replay(mActivityManager, mPowerManager, mStatsService, mPolicyListener, mTime, - mConnManager); + mConnManager, mNotifManager); } private void verifyAndReset() { EasyMock.verify(mActivityManager, mPowerManager, mStatsService, mPolicyListener, mTime, - mConnManager); + mConnManager, mNotifManager); EasyMock.reset(mActivityManager, mPowerManager, mStatsService, mPolicyListener, mTime, - mConnManager); + mConnManager, mNotifManager); } } diff --git a/telephony/java/com/android/internal/telephony/DataCallState.java b/telephony/java/com/android/internal/telephony/DataCallState.java index 1d67d45..f5651e0 100644 --- a/telephony/java/com/android/internal/telephony/DataCallState.java +++ b/telephony/java/com/android/internal/telephony/DataCallState.java @@ -202,7 +202,7 @@ public class DataCallState { result = SetupResult.SUCCESS; } catch (UnknownHostException e) { - Log.d(LOG_TAG, "onSetupCompleted: UnknownHostException " + e); + Log.d(LOG_TAG, "setLinkProperties: UnknownHostException " + e); e.printStackTrace(); result = SetupResult.ERR_UnacceptableParameter; } @@ -216,8 +216,10 @@ public class DataCallState { // An error occurred so clear properties if (result != SetupResult.SUCCESS) { - if(DBG) Log.d(LOG_TAG, - "onSetupConnectionCompleted with an error, clearing LinkProperties"); + if(DBG) { + Log.d(LOG_TAG, "setLinkProperties: error clearing LinkProperties " + + "status=" + status + " result=" + result); + } linkProperties.clear(); } diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java index c21a96a..5c030fd 100644 --- a/telephony/java/com/android/internal/telephony/DataConnection.java +++ b/telephony/java/com/android/internal/telephony/DataConnection.java @@ -228,7 +228,6 @@ public abstract class DataConnection extends StateMachine { mId = id; mRetryMgr = rm; this.cid = -1; - clearSettings(); setDbg(false); addState(mDefaultState); @@ -313,7 +312,6 @@ public abstract class DataConnection extends StateMachine { AsyncResult.forMessage(msg); msg.sendToTarget(); } - clearSettings(); if (DBG) log("NotifyDisconnectCompleted DisconnectParams=" + dp); } @@ -632,7 +630,6 @@ public abstract class DataConnection extends StateMachine { } case DataConnectionAc.REQ_RESET: if (VDBG) log("DcDefaultState: msg.what=REQ_RESET"); - clearSettings(); mAc.replyToMessage(msg, DataConnectionAc.RSP_RESET); transitionTo(mInactiveState); break; @@ -718,6 +715,7 @@ public abstract class DataConnection extends StateMachine { if (VDBG) log("DcInactiveState: enter notifyDisconnectCompleted"); notifyDisconnectCompleted(mDisconnectParams); } + clearSettings(); } @Override diff --git a/telephony/java/com/android/internal/telephony/IccCard.java b/telephony/java/com/android/internal/telephony/IccCard.java index 5d8fc78..02617c8 100644 --- a/telephony/java/com/android/internal/telephony/IccCard.java +++ b/telephony/java/com/android/internal/telephony/IccCard.java @@ -84,6 +84,9 @@ public abstract class IccCard { static public final String INTENT_VALUE_LOCKED_ON_PUK = "PUK"; /* NETWORK means ICC is locked on NETWORK PERSONALIZATION */ static public final String INTENT_VALUE_LOCKED_NETWORK = "NETWORK"; + /* PERM_DISABLED means ICC is permanently disabled due to puk fails */ + static public final String INTENT_VALUE_ABSENT_ON_PERM_DISABLED = "PERM_DISABLED"; + protected static final int EVENT_ICC_LOCKED_OR_ABSENT = 1; private static final int EVENT_GET_ICC_STATUS_DONE = 2; @@ -112,7 +115,8 @@ public abstract class IccCard { PUK_REQUIRED, NETWORK_LOCKED, READY, - NOT_READY; + NOT_READY, + PERM_DISABLED; public boolean isPinLocked() { return ((this == PIN_REQUIRED) || (this == PUK_REQUIRED)); @@ -120,7 +124,8 @@ public abstract class IccCard { public boolean iccCardExist() { return ((this == PIN_REQUIRED) || (this == PUK_REQUIRED) - || (this == NETWORK_LOCKED) || (this == READY)); + || (this == NETWORK_LOCKED) || (this == READY) + || (this == PERM_DISABLED)); } } @@ -416,6 +421,7 @@ public abstract class IccCard { boolean transitionedIntoPinLocked; boolean transitionedIntoAbsent; boolean transitionedIntoNetworkLocked; + boolean transitionedIntoPermBlocked; boolean isIccCardRemoved; boolean isIccCardAdded; @@ -434,6 +440,8 @@ public abstract class IccCard { transitionedIntoAbsent = (oldState != State.ABSENT && newState == State.ABSENT); transitionedIntoNetworkLocked = (oldState != State.NETWORK_LOCKED && newState == State.NETWORK_LOCKED); + transitionedIntoPermBlocked = (oldState != State.PERM_DISABLED + && newState == State.PERM_DISABLED); isIccCardRemoved = (oldState != null && oldState.iccCardExist() && newState == State.ABSENT); isIccCardAdded = (oldState == State.ABSENT && @@ -454,6 +462,10 @@ public abstract class IccCard { mNetworkLockedRegistrants.notifyRegistrants(); broadcastIccStateChangedIntent(INTENT_VALUE_ICC_LOCKED, INTENT_VALUE_LOCKED_NETWORK); + } else if (transitionedIntoPermBlocked) { + if (mDbg) log("Notify SIM permanently disabled."); + broadcastIccStateChangedIntent(INTENT_VALUE_ICC_ABSENT, + INTENT_VALUE_ABSENT_ON_PERM_DISABLED); } if (isIccCardRemoved) { @@ -762,6 +774,9 @@ public abstract class IccCard { } // check if PIN required + if (app.pin1.isPermBlocked()) { + return IccCard.State.PERM_DISABLED; + } if (app.app_state.isPinRequired()) { return IccCard.State.PIN_REQUIRED; } diff --git a/telephony/java/com/android/internal/telephony/IccCardApplication.java b/telephony/java/com/android/internal/telephony/IccCardApplication.java index 434c484..abb740e 100644 --- a/telephony/java/com/android/internal/telephony/IccCardApplication.java +++ b/telephony/java/com/android/internal/telephony/IccCardApplication.java @@ -16,6 +16,8 @@ package com.android.internal.telephony; +import com.android.internal.telephony.IccCardStatus.PinState; + /** * See also RIL_AppStatus in include/telephony/ril.h @@ -104,8 +106,8 @@ public class IccCardApplication { public String app_label; // applicable to USIM and CSIM public int pin1_replaced; - public int pin1; - public int pin2; + public PinState pin1; + public PinState pin2; AppType AppTypeFromRILInt(int type) { AppType newType; @@ -177,6 +179,33 @@ public class IccCardApplication { return newSubState; } + PinState PinStateFromRILInt(int state) { + PinState newPinState; + switch(state) { + case 0: + newPinState = PinState.PINSTATE_UNKNOWN; + break; + case 1: + newPinState = PinState.PINSTATE_ENABLED_NOT_VERIFIED; + break; + case 2: + newPinState = PinState.PINSTATE_ENABLED_VERIFIED; + break; + case 3: + newPinState = PinState.PINSTATE_DISABLED; + break; + case 4: + newPinState = PinState.PINSTATE_ENABLED_BLOCKED; + break; + case 5: + newPinState = PinState.PINSTATE_ENABLED_PERM_BLOCKED; + break; + default: + throw new RuntimeException("Unrecognized RIL_PinState: " + state); + } + return newPinState; + } + @Override public String toString() { StringBuilder sb = new StringBuilder(); @@ -185,6 +214,12 @@ public class IccCardApplication { if (app_state == AppState.APPSTATE_SUBSCRIPTION_PERSO) { sb.append(",").append(perso_substate); } + if (app_type == AppType.APPTYPE_CSIM || + app_type == AppType.APPTYPE_USIM || + app_type == AppType.APPTYPE_ISIM) { + sb.append(",pin1=").append(pin1); + sb.append(",pin2=").append(pin2); + } sb.append("}"); return sb.toString(); } diff --git a/telephony/java/com/android/internal/telephony/IccCardStatus.java b/telephony/java/com/android/internal/telephony/IccCardStatus.java index e9de922..c751a21 100644 --- a/telephony/java/com/android/internal/telephony/IccCardStatus.java +++ b/telephony/java/com/android/internal/telephony/IccCardStatus.java @@ -42,7 +42,19 @@ public class IccCardStatus { PINSTATE_ENABLED_VERIFIED, PINSTATE_DISABLED, PINSTATE_ENABLED_BLOCKED, - PINSTATE_ENABLED_PERM_BLOCKED + PINSTATE_ENABLED_PERM_BLOCKED; + + boolean isPermBlocked() { + return this == PINSTATE_ENABLED_PERM_BLOCKED; + } + + boolean isPinRequired() { + return this == PINSTATE_ENABLED_NOT_VERIFIED; + } + + boolean isPukRequired() { + return this == PINSTATE_ENABLED_BLOCKED; + } } private CardState mCardState; diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java index 572bbaa..76f1ab7 100644 --- a/telephony/java/com/android/internal/telephony/RIL.java +++ b/telephony/java/com/android/internal/telephony/RIL.java @@ -2924,8 +2924,8 @@ public final class RIL extends BaseCommands implements CommandsInterface { ca.aid = p.readString(); ca.app_label = p.readString(); ca.pin1_replaced = p.readInt(); - ca.pin1 = p.readInt(); - ca.pin2 = p.readInt(); + ca.pin1 = ca.PinStateFromRILInt(p.readInt()); + ca.pin2 = ca.PinStateFromRILInt(p.readInt()); status.addApplication(ca); } return status; diff --git a/telephony/java/com/android/internal/telephony/WapPushOverSms.java b/telephony/java/com/android/internal/telephony/WapPushOverSms.java index e2779dc..e2779dc 100644..100755 --- a/telephony/java/com/android/internal/telephony/WapPushOverSms.java +++ b/telephony/java/com/android/internal/telephony/WapPushOverSms.java diff --git a/telephony/java/com/android/internal/telephony/WspTypeDecoder.java b/telephony/java/com/android/internal/telephony/WspTypeDecoder.java index c8dd718..73260fb 100644..100755 --- a/telephony/java/com/android/internal/telephony/WspTypeDecoder.java +++ b/telephony/java/com/android/internal/telephony/WspTypeDecoder.java @@ -194,6 +194,7 @@ public class WspTypeDecoder { public static final String CONTENT_TYPE_B_PUSH_CO = "application/vnd.wap.coc"; public static final String CONTENT_TYPE_B_MMS = "application/vnd.wap.mms-message"; + public static final String CONTENT_TYPE_B_PUSH_SYNCML_NOTI = "application/vnd.syncml.notification"; byte[] wspData; int dataLength; diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java index 29349db..07b0f4f 100644..100755 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java @@ -41,6 +41,7 @@ import com.android.internal.telephony.SmsHeader; import com.android.internal.telephony.SmsMessageBase; import com.android.internal.telephony.SmsMessageBase.TextEncodingDetails; import com.android.internal.telephony.TelephonyProperties; +import com.android.internal.telephony.WspTypeDecoder; import com.android.internal.telephony.cdma.sms.SmsEnvelope; import com.android.internal.telephony.cdma.sms.UserData; import com.android.internal.util.HexDump; @@ -50,6 +51,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import android.content.res.Resources; + final class CdmaSMSDispatcher extends SMSDispatcher { private static final String TAG = "CDMA"; @@ -57,6 +60,9 @@ final class CdmaSMSDispatcher extends SMSDispatcher { private byte[] mLastDispatchedSmsFingerprint; private byte[] mLastAcknowledgedSmsFingerprint; + private boolean mCheckForDuplicatePortsInOmadmWapPush = Resources.getSystem().getBoolean( + com.android.internal.R.bool.config_duplicate_port_omadm_wappush); + CdmaSMSDispatcher(CDMAPhone phone) { super(phone); } @@ -253,6 +259,13 @@ final class CdmaSMSDispatcher extends SMSDispatcher { sourcePort |= 0xFF & pdu[index++]; destinationPort = (0xFF & pdu[index++]) << 8; destinationPort |= 0xFF & pdu[index++]; + // Some carriers incorrectly send duplicate port fields in omadm wap pushes. + // If configured, check for that here + if (mCheckForDuplicatePortsInOmadmWapPush) { + if (checkDuplicatePortOmadmWappush(pdu,index)) { + index = index + 4; // skip duplicate port fields + } + } } // Lookup all other related parts @@ -502,4 +515,42 @@ final class CdmaSMSDispatcher extends SMSDispatcher { return CommandsInterface.CDMA_SMS_FAIL_CAUSE_ENCODING_PROBLEM; } } + + /** + * Optional check to see if the received WapPush is an OMADM notification with erroneous + * extra port fields. + * - Some carriers make this mistake. + * ex: MSGTYPE-TotalSegments-CurrentSegment + * -SourcePortDestPort-SourcePortDestPort-OMADM PDU + * @param origPdu The WAP-WDP PDU segment + * @param index Current Index while parsing the PDU. + * @return True if OrigPdu is OmaDM Push Message which has duplicate ports. + * False if OrigPdu is NOT OmaDM Push Message which has duplicate ports. + */ + private boolean checkDuplicatePortOmadmWappush(byte[] origPdu, int index) { + index += 4; + byte[] omaPdu = new byte[origPdu.length - index]; + System.arraycopy(origPdu, index, omaPdu, 0, omaPdu.length); + + WspTypeDecoder pduDecoder = new WspTypeDecoder(omaPdu); + int wspIndex = 2; + + // Process header length field + if (pduDecoder.decodeUintvarInteger(wspIndex) == false) { + return false; + } + + wspIndex += pduDecoder.getDecodedDataLength(); // advance to next field + + // Process content type field + if (pduDecoder.decodeContentType(wspIndex) == false) { + return false; + } + + String mimeType = pduDecoder.getValueString(); + if (mimeType != null && mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_SYNCML_NOTI)) { + return true; + } + return false; + } } diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java index ee63ede..9af2d26 100755 --- a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java +++ b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java @@ -119,8 +119,11 @@ public final class RuimRecords extends IccRecords { adnCache.reset(); - phone.setSystemProperty(PROPERTY_ICC_OPERATOR_NUMERIC, null); - phone.setSystemProperty(PROPERTY_ICC_OPERATOR_ISO_COUNTRY, null); + // Don't clean up PROPERTY_ICC_OPERATOR_ISO_COUNTRY and + // PROPERTY_ICC_OPERATOR_NUMERIC here. Since not all CDMA + // devices have RUIM, these properties should keep the original + // values, e.g. build time settings, when there is no RUIM but + // set new values when RUIM is available and loaded. // recordsRequested is set to false indicating that the SIM // read requests made so far are not valid. This is set to diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java index dcde71a..19c06f6 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java @@ -1850,7 +1850,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { if (!dc.configureRetry(SystemProperties.get("ro.gsm.data_retry_config"))) { if (!dc.configureRetry(DEFAULT_DATA_RETRY_CONFIG)) { // Should never happen, log an error and default to a simple linear sequence. - loge("createDataConnection: Could not configure using " + + loge("configureRetry: Could not configure using " + "DEFAULT_DATA_RETRY_CONFIG=" + DEFAULT_DATA_RETRY_CONFIG); dc.configureRetry(20, 2000, 1000); } @@ -1859,7 +1859,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { if (!dc.configureRetry(SystemProperties.get("ro.gsm.2nd_data_retry_config"))) { if (!dc.configureRetry(SECONDARY_DATA_RETRY_CONFIG)) { // Should never happen, log an error and default to a simple sequence. - loge("createDataConnection: Could note configure using " + + loge("configureRetry: Could note configure using " + "SECONDARY_DATA_RETRY_CONFIG=" + SECONDARY_DATA_RETRY_CONFIG); dc.configureRetry("max_retries=3, 333, 333, 333"); } @@ -1872,7 +1872,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { if (DBG) log("destroyDataConnections: clear mDataConnectionList"); mDataConnections.clear(); } else { - if (DBG) log("destroyDataConnectionList mDataConnecitonList is empty, ignore"); + if (DBG) log("destroyDataConnections: mDataConnecitonList is empty, ignore"); } } 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/RenderScriptTests/PerfTest/res/drawable/flares.png b/tests/RenderScriptTests/PerfTest/res/drawable/flares.png Binary files differnew file mode 100644 index 0000000..3a5c970 --- /dev/null +++ b/tests/RenderScriptTests/PerfTest/res/drawable/flares.png diff --git a/tests/RenderScriptTests/PerfTest/res/drawable/light1.jpg b/tests/RenderScriptTests/PerfTest/res/drawable/light1.jpg Binary files differnew file mode 100644 index 0000000..2f2f10e --- /dev/null +++ b/tests/RenderScriptTests/PerfTest/res/drawable/light1.jpg diff --git a/tests/RenderScriptTests/PerfTest/res/drawable/space.jpg b/tests/RenderScriptTests/PerfTest/res/drawable/space.jpg Binary files differnew file mode 100644 index 0000000..b61f6a3 --- /dev/null +++ b/tests/RenderScriptTests/PerfTest/res/drawable/space.jpg diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java index b568781..3f57799 100644 --- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java +++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java @@ -38,6 +38,10 @@ import android.renderscript.ProgramStore.BlendSrcFunc; import android.renderscript.ProgramStore.BlendDstFunc; import android.renderscript.RenderScript.RSMessageHandler; import android.renderscript.Sampler.Value; +import android.renderscript.Mesh.Primitive; +import android.renderscript.Matrix4f; +import android.renderscript.ProgramVertexFixedFunction; + import android.util.Log; @@ -45,7 +49,9 @@ public class RsBenchRS { private static final String TAG = "RsBenchRS"; private static final String SAMPLE_TEXT = "Bench Test"; - + private static final String LIST_TEXT = + "This is a sample list of text to show in the list view"; + private static int PARTICLES_COUNT = 12000; int mWidth; int mHeight; int mLoops; @@ -82,6 +88,7 @@ public class RsBenchRS { private Sampler mLinearWrap; private Sampler mMipLinearWrap; private Sampler mNearestClamp; + private Sampler mNearesWrap; private ProgramStore mProgStoreBlendNoneDepth; private ProgramStore mProgStoreBlendNone; @@ -106,6 +113,7 @@ public class RsBenchRS { private ScriptField_VertexShaderConstants3_s mVSConstPixel; private ScriptField_FragentShaderConstants3_s mFSConstPixel; + private ProgramRaster mCullBack; private ProgramRaster mCullFront; private ProgramRaster mCullNone; @@ -121,6 +129,7 @@ public class RsBenchRS { private Mesh mWbyHMesh; private Mesh mTorus; private Mesh mSingleMesh; + private Mesh mParticlesMesh; Font mFontSans; Font mFontSerif; @@ -128,6 +137,9 @@ public class RsBenchRS { private ScriptField_ListAllocs_s mTextureAllocs; private ScriptField_ListAllocs_s mSampleTextAllocs; + private ScriptField_ListAllocs_s mSampleListViewAllocs; + private ScriptField_VpConsts mPvStarAlloc; + private ScriptC_rsbench mScript; @@ -300,6 +312,15 @@ public class RsBenchRS { mScript.set_gProgStoreBlendNone(mProgStoreBlendNone); mScript.set_gProgStoreBlendAlpha(mProgStoreBlendAlpha); mScript.set_gProgStoreBlendAdd(mProgStoreBlendAdd); + + // For GALAXY + builder = new ProgramStore.Builder(mRS); + builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO); + mRS.bindProgramStore(builder.create()); + + builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE); + mScript.set_gPSLights(builder.create()); + } private void initProgramFragment() { @@ -316,8 +337,59 @@ public class RsBenchRS { mScript.set_gProgFragmentColor(mProgFragmentColor); mScript.set_gProgFragmentTexture(mProgFragmentTexture); + + + // For Galaxy live wallpaper drawing + ProgramFragmentFixedFunction.Builder builder = new ProgramFragmentFixedFunction.Builder(mRS); + builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE, + ProgramFragmentFixedFunction.Builder.Format.RGB, 0); + ProgramFragment pfb = builder.create(); + pfb.bindSampler(mNearesWrap, 0); + mScript.set_gPFBackground(pfb); + + builder = new ProgramFragmentFixedFunction.Builder(mRS); + builder.setPointSpriteTexCoordinateReplacement(true); + builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.MODULATE, + ProgramFragmentFixedFunction.Builder.Format.RGBA, 0); + builder.setVaryingColor(true); + ProgramFragment pfs = builder.create(); + pfs.bindSampler(mMipLinearWrap, 0); + mScript.set_gPFStars(pfs); + } + private Matrix4f getProjectionNormalized(int w, int h) { + // range -1,1 in the narrow axis at z = 0. + Matrix4f m1 = new Matrix4f(); + Matrix4f m2 = new Matrix4f(); + + if(w > h) { + float aspect = ((float)w) / h; + m1.loadFrustum(-aspect,aspect, -1,1, 1,100); + } else { + float aspect = ((float)h) / w; + m1.loadFrustum(-1,1, -aspect,aspect, 1,100); + } + + m2.loadRotate(180, 0, 1, 0); + m1.loadMultiply(m1, m2); + + m2.loadScale(-2, 2, 1); + m1.loadMultiply(m1, m2); + + m2.loadTranslate(0, 0, 2); + m1.loadMultiply(m1, m2); + return m1; + } + + private void updateProjectionMatrices() { + Matrix4f projNorm = getProjectionNormalized(mBenchmarkDimX, mBenchmarkDimY); + ScriptField_VpConsts.Item i = new ScriptField_VpConsts.Item(); + i.Proj = projNorm; + i.MVP = projNorm; + mPvStarAlloc.set(i, 0, true); + } + private void initProgramVertex() { ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS); mProgVertex = pvb.create(); @@ -329,6 +401,39 @@ public class RsBenchRS { mPVA.setProjection(proj); mScript.set_gProgVertex(mProgVertex); + + // For galaxy live wallpaper + mPvStarAlloc = new ScriptField_VpConsts(mRS, 1); + mScript.bind_vpConstants(mPvStarAlloc); + updateProjectionMatrices(); + + ProgramVertex.Builder sb = new ProgramVertex.Builder(mRS); + String t = "varying vec4 varColor;\n" + + "varying vec2 varTex0;\n" + + "void main() {\n" + + " float dist = ATTRIB_position.y;\n" + + " float angle = ATTRIB_position.x;\n" + + " float x = dist * sin(angle);\n" + + " float y = dist * cos(angle) * 0.892;\n" + + " float p = dist * 5.5;\n" + + " float s = cos(p);\n" + + " float t = sin(p);\n" + + " vec4 pos;\n" + + " pos.x = t * x + s * y;\n" + + " pos.y = s * x - t * y;\n" + + " pos.z = ATTRIB_position.z;\n" + + " pos.w = 1.0;\n" + + " gl_Position = UNI_MVP * pos;\n" + + " gl_PointSize = ATTRIB_color.a * 10.0;\n" + + " varColor.rgb = ATTRIB_color.rgb;\n" + + " varColor.a = 1.0;\n" + + "}\n"; + sb.setShader(t); + sb.addInput(mParticlesMesh.getVertexAllocation(0).getType().getElement()); + sb.addConstant(mPvStarAlloc.getType()); + ProgramVertex pvs = sb.create(); + pvs.bindConstants(mPvStarAlloc.getAllocation(), 0); + mScript.set_gPVStars(pvs); } private void initCustomShaders() { @@ -426,6 +531,11 @@ public class RsBenchRS { mScript.set_gTexTransparent(mTexTransparent); mScript.set_gTexChecker(mTexChecker); mScript.set_gTexGlobe(mTexGlobe); + + // For Galaxy live wallpaper + mScript.set_gTSpace(loadTextureRGB(R.drawable.space)); + mScript.set_gTLight1(loadTextureRGB(R.drawable.light1)); + mScript.set_gTFlares(loadTextureARGB(R.drawable.flares)); } private void initFonts() { @@ -440,6 +550,19 @@ public class RsBenchRS { mScript.set_gFontSerif(mFontSerif); } + private void createParticlesMesh() { + ScriptField_Particle p = new ScriptField_Particle(mRS, PARTICLES_COUNT); + + final Mesh.AllocationBuilder meshBuilder = new Mesh.AllocationBuilder(mRS); + meshBuilder.addVertexAllocation(p.getAllocation()); + final int vertexSlot = meshBuilder.getCurrentVertexTypeIndex(); + meshBuilder.addIndexSetType(Primitive.POINT); + mParticlesMesh = meshBuilder.create(); + + mScript.set_gParticlesMesh(mParticlesMesh); + mScript.bind_Particles(p); + } + private void initMesh() { m10by10Mesh = getMbyNMesh(mBenchmarkDimX, mBenchmarkDimY, 10, 10); mScript.set_g10by10Mesh(m10by10Mesh); @@ -458,6 +581,8 @@ public class RsBenchRS { mTorus = (Mesh)entry.getObject(); mScript.set_gTorusMesh(mTorus); } + + createParticlesMesh(); } private void initSamplers() { @@ -471,6 +596,7 @@ public class RsBenchRS { mLinearClamp = Sampler.CLAMP_LINEAR(mRS); mNearestClamp = Sampler.CLAMP_NEAREST(mRS); mMipLinearWrap = Sampler.WRAP_LINEAR_MIP_LINEAR(mRS); + mNearesWrap = Sampler.WRAP_NEAREST(mRS); mScript.set_gLinearClamp(mLinearClamp); mScript.set_gLinearWrap(mLinearWrap); @@ -524,10 +650,10 @@ public class RsBenchRS { initSamplers(); initProgramStore(); initProgramFragment(); + initMesh(); initProgramVertex(); initFonts(); loadImages(); - initMesh(); initProgramRaster(); initCustomShaders(); @@ -567,6 +693,15 @@ public class RsBenchRS { mSampleTextAllocs.copyAll(); mScript.bind_gSampleTextList100(mSampleTextAllocs); + mSampleListViewAllocs = new ScriptField_ListAllocs_s(mRS, 1000); + for (int i = 0; i < 1000; i++) { + ScriptField_ListAllocs_s.Item textElem = new ScriptField_ListAllocs_s.Item(); + textElem.item = Allocation.createFromString(mRS, LIST_TEXT, Allocation.USAGE_SCRIPT); + mSampleListViewAllocs.set(textElem, i, false); + } + mSampleListViewAllocs.copyAll(); + mScript.bind_gListViewText(mSampleListViewAllocs); + mRS.bindRootScript(mScript); } } diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs index 0294b31..6d80b0e 100644 --- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs +++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs @@ -23,9 +23,50 @@ const int RS_MSG_TEST_DONE = 100; const int RS_MSG_RESULTS_READY = 101; -const int gMaxModes = 29; +const int gMaxModes = 31; int gMaxLoops; +// Parameters for galaxy live wallpaper +rs_allocation gTSpace; +rs_allocation gTLight1; +rs_allocation gTFlares; +rs_mesh gParticlesMesh; + +rs_program_fragment gPFBackground; +rs_program_fragment gPFStars; +rs_program_vertex gPVStars; +rs_program_vertex gPVBkProj; +rs_program_store gPSLights; + +float gXOffset = 0.5f; + +#define ELLIPSE_RATIO 0.892f +#define PI 3.1415f +#define TWO_PI 6.283f +#define ELLIPSE_TWIST 0.023333333f + +static float angle = 50.f; +static int gOldWidth; +static int gOldHeight; +static int gWidth; +static int gHeight; +static float gSpeed[12000]; +static int gGalaxyRadius = 300; +static rs_allocation gParticlesBuffer; + +typedef struct __attribute__((packed, aligned(4))) Particle { + uchar4 color; + float3 position; +} Particle_t; +Particle_t *Particles; + +typedef struct VpConsts { + rs_matrix4x4 Proj; + rs_matrix4x4 MVP; +} VpConsts_t; +VpConsts_t *vpConstants; +// End of parameters for galaxy live wallpaper + // Allocation to send test names back to java char *gStringBuffer = 0; // Allocation to write the results into @@ -52,6 +93,7 @@ typedef struct ListAllocs_s { ListAllocs *gTexList100; ListAllocs *gSampleTextList100; +ListAllocs *gListViewText; rs_mesh g10by10Mesh; rs_mesh g100by100Mesh; @@ -109,6 +151,141 @@ static float textColors[] = {1.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.6f, 0.7f, 1.0f, }; +/** + * Methods to draw the galaxy live wall paper + */ +static float mapf(float minStart, float minStop, float maxStart, float maxStop, float value) { + return maxStart + (maxStart - maxStop) * ((value - minStart) / (minStop - minStart)); +} + +/** + * Helper function to generate the stars. + */ +static float randomGauss() { + float x1; + float x2; + float w = 2.f; + + while (w >= 1.0f) { + x1 = rsRand(2.0f) - 1.0f; + x2 = rsRand(2.0f) - 1.0f; + w = x1 * x1 + x2 * x2; + } + + w = sqrt(-2.0f * log(w) / w); + return x1 * w; +} + +/** + * Generates the properties for a given star. + */ +static void createParticle(Particle_t *part, int idx, float scale) { + float d = fabs(randomGauss()) * gGalaxyRadius * 0.5f + rsRand(64.0f); + float id = d / gGalaxyRadius; + float z = randomGauss() * 0.4f * (1.0f - id); + float p = -d * ELLIPSE_TWIST; + + if (d < gGalaxyRadius * 0.33f) { + part->color.x = (uchar) (220 + id * 35); + part->color.y = 220; + part->color.z = 220; + } else { + part->color.x = 180; + part->color.y = 180; + part->color.z = (uchar) clamp(140.f + id * 115.f, 140.f, 255.f); + } + // Stash point size * 10 in Alpha + part->color.w = (uchar) (rsRand(1.2f, 2.1f) * 60); + + if (d > gGalaxyRadius * 0.15f) { + z *= 0.6f * (1.0f - id); + } else { + z *= 0.72f; + } + + // Map to the projection coordinates (viewport.x = -1.0 -> 1.0) + d = mapf(-4.0f, gGalaxyRadius + 4.0f, 0.0f, scale, d); + + part->position.x = rsRand(TWO_PI); + part->position.y = d; + gSpeed[idx] = rsRand(0.0015f, 0.0025f) * (0.5f + (scale / d)) * 0.8f; + + part->position.z = z / 5.0f; +} + +/** + * Initialize all the starts, called from Java + */ +void initParticles() { + Particle_t *part = Particles; + float scale = gGalaxyRadius / (gWidth * 0.5f); + int count = rsAllocationGetDimX(gParticlesBuffer); + for (int i = 0; i < count; i ++) { + createParticle(part, i, scale); + part++; + } +} + +static void drawSpace() { + rsgBindProgramFragment(gPFBackground); + rsgBindTexture(gPFBackground, 0, gTSpace); + rsgDrawQuadTexCoords( + 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, + gWidth, 0.0f, 0.0f, 2.0f, 1.0f, + gWidth, gHeight, 0.0f, 2.0f, 0.0f, + 0.0f, gHeight, 0.0f, 0.0f, 0.0f); +} + +static void drawLights() { + rsgBindProgramVertex(gPVBkProj); + rsgBindProgramFragment(gPFBackground); + rsgBindTexture(gPFBackground, 0, gTLight1); + + float scale = 512.0f / gWidth; + float x = -scale - scale * 0.05f; + float y = -scale; + + scale *= 2.0f; + + rsgDrawQuad(x, y, 0.0f, + x + scale * 1.1f, y, 0.0f, + x + scale * 1.1f, y + scale, 0.0f, + x, y + scale, 0.0f); +} + +static void drawParticles(float offset) { + float a = offset * angle; + float absoluteAngle = fabs(a); + + rs_matrix4x4 matrix; + rsMatrixLoadTranslate(&matrix, 0.0f, 0.0f, 10.0f - 6.0f * absoluteAngle / 50.0f); + if (gHeight > gWidth) { + rsMatrixScale(&matrix, 6.6f, 6.0f, 1.0f); + } else { + rsMatrixScale(&matrix, 12.6f, 12.0f, 1.0f); + } + rsMatrixRotate(&matrix, absoluteAngle, 1.0f, 0.0f, 0.0f); + rsMatrixRotate(&matrix, a, 0.0f, 0.4f, 0.1f); + rsMatrixLoad(&vpConstants->MVP, &vpConstants->Proj); + rsMatrixMultiply(&vpConstants->MVP, &matrix); + rsgAllocationSyncAll(rsGetAllocation(vpConstants)); + + rsgBindProgramVertex(gPVStars); + rsgBindProgramFragment(gPFStars); + rsgBindProgramStore(gPSLights); + rsgBindTexture(gPFStars, 0, gTFlares); + + Particle_t *vtx = Particles; + int count = rsAllocationGetDimX(gParticlesBuffer); + for (int i = 0; i < count; i++) { + vtx->position.x = vtx->position.x + gSpeed[i]; + vtx++; + } + + rsgDrawMesh(gParticlesMesh); +} +/* end of methods for drawing galaxy */ + static void setupOffscreenTarget() { rsgBindColorTarget(gRenderBufferColor, 0); rsgBindDepthTarget(gRenderBufferDepth); @@ -303,6 +480,71 @@ static void displayImageWithText(int wResolution, int hResolution, int meshMode) } } +// Display a list of text as the list view +static void displayListView() { + // set text color + rsgFontColor(0.9f, 0.9f, 0.9f, 1.0f); + rsgBindFont(gFontSans); + + // get the size of the list + rs_allocation textAlloc; + textAlloc = rsGetAllocation(gListViewText); + int allocSize = rsAllocationGetDimX(textAlloc); + + int listItemHeight = 80; + int yOffset = listItemHeight; + + // set the color for the list divider + rsgBindProgramFragment(gProgFragmentColor); + rsgProgramFragmentConstantColor(gProgFragmentColor, 1.0, 1.0, 1.0, 1); + + // draw the list with divider + for (int i = 0; i < allocSize; i++) { + if (yOffset - listItemHeight > gRenderSurfaceH) { + break; + } + rsgDrawRect(0, yOffset - 1, gRenderSurfaceW, yOffset, 0); + rsgDrawText(gListViewText[i].item, 20, yOffset - 10); + yOffset += listItemHeight; + } +} + +static void drawGalaxy() { + rsgClearColor(0.f, 0.f, 0.f, 1.f); + gParticlesBuffer = rsGetAllocation(Particles); + rsgBindProgramFragment(gPFBackground); + + gWidth = rsgGetWidth(); + gHeight = rsgGetHeight(); + if ((gWidth != gOldWidth) || (gHeight != gOldHeight)) { + initParticles(); + gOldWidth = gWidth; + gOldHeight = gHeight; + } + + float offset = mix(-1.0f, 1.0f, gXOffset); + drawSpace(); + drawParticles(offset); + drawLights(); +} + +// Display images and text with live wallpaper in the background +static void dispalyLiveWallPaper(int wResolution, int hResolution) { + bindProgramVertexOrtho(); + + drawGalaxy(); + + rsgBindProgramStore(gProgStoreBlendAlpha); + rsgBindProgramFragment(gProgFragmentTexture); + rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp); + + drawMeshInPage(0, 0, wResolution, hResolution); + drawMeshInPage(-1.0f*gRenderSurfaceW, 0, wResolution, hResolution); + drawMeshInPage(1.0f*gRenderSurfaceW, 0, wResolution, hResolution); + drawMeshInPage(-2.0f*gRenderSurfaceW, 0, wResolution, hResolution); + drawMeshInPage(2.0f*gRenderSurfaceW, 0, wResolution, hResolution); +} + static float gTorusRotation = 0; static void updateModelMatrix(rs_matrix4x4 *matrix, void *buffer) { if (buffer == 0) { @@ -602,14 +844,12 @@ static const char *testNames[] = { "Geo test 25.6k heavy fragment heavy vertex", "Geo test 51.2k heavy fragment heavy vertex", "Geo test 204.8k small tries heavy fragment heavy vertex", - "UI test with icon display 10 by 10", // 25 - "UI test with icon display 100 by 100", // 26 - "UI test with image and text display 3 pages", // 27 - "UI test with image and text display 5 pages", // 28 - "UI test with list view", // 29 -// "UI test with live wallpaper", // 30 -// "Mesh with 10 by 10 texture", -// "Mesh with 100 by 100 texture", + "UI test with icon display 10 by 10", + "UI test with icon display 100 by 100", + "UI test with image and text display 3 pages", + "UI test with image and text display 5 pages", + "UI test with list view", + "UI test with live wallpaper", }; void getTestName(int testIndex) { @@ -714,6 +954,12 @@ static void runTest(int index) { case 28: displayImageWithText(7, 5, 1); break; + case 29: + displayListView(); + break; + case 30: + dispalyLiveWallPaper(7, 5); + break; } } @@ -737,7 +983,6 @@ static void drawOffscreenResult(int posX, int posY, int width, int height) { } int root(void) { - gRenderSurfaceW = rsgGetWidth(); gRenderSurfaceH = rsgGetHeight(); rsgClearColor(0.2f, 0.2f, 0.2f, 1.0f); diff --git a/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/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java index 8e3ed93..b4448a9 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java @@ -1093,6 +1093,33 @@ public final class Canvas_Delegate { } @LayoutlibDelegate + /*package*/ static void native_drawTextWithGlyphs(int nativeCanvas, char[] text, + int index, int count, float x, + float y, int flags, int paint) { + native_drawText(nativeCanvas, text, index, count, x, y, flags, paint); + } + + @LayoutlibDelegate + /*package*/ static void native_drawTextWithGlyphs(int nativeCanvas, String text, + int start, int end, float x, + float y, int flags, int paint) { + int count = end - start; + char[] buffer = TemporaryBuffer.obtain(count); + TextUtils.getChars(text, start, end, buffer, 0); + + native_drawText(nativeCanvas, text, 0, count, x, y, flags, paint); + } + + @LayoutlibDelegate + /*package*/ static void native_drawGlyphs(int nativeCanvas, char[] glyphs, + int index, int count, float x, + float y, int flags, int paint) { + // FIXME + Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, + "Canvas.drawGlyphs is not supported.", null, null /*data*/); + } + + @LayoutlibDelegate /*package*/ static void native_drawPosText(int nativeCanvas, char[] text, int index, int count, float[] pos, diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java index 373f482..7777e19 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java @@ -940,9 +940,16 @@ public class Paint_Delegate { } @LayoutlibDelegate + /* package */static int native_getTextGlyphs(int native_object, String text, int start, + int end, int contextStart, int contextEnd, int flags, char[] glyphs) { + // FIXME + return 0; + } + + @LayoutlibDelegate /*package*/ static float native_getTextRunAdvances(int native_object, char[] text, int index, int count, int contextIndex, int contextCount, - int flags, float[] advances, int advancesIndex) { + int flags, float[] advances, int advancesIndex, int reserved) { // get the delegate from the native int. Paint_Delegate delegate = sManager.getDelegate(native_object); if (delegate == null) { @@ -986,14 +993,14 @@ public class Paint_Delegate { @LayoutlibDelegate /*package*/ static float native_getTextRunAdvances(int native_object, String text, int start, int end, int contextStart, int contextEnd, - int flags, float[] advances, int advancesIndex) { + int flags, float[] advances, int advancesIndex, int reserved) { // FIXME: support contextStart, contextEnd and direction flag int count = end - start; char[] buffer = TemporaryBuffer.obtain(count); TextUtils.getChars(text, start, end, buffer, 0); return native_getTextRunAdvances(native_object, buffer, 0, count, contextStart, - contextEnd - contextStart, flags, advances, advancesIndex); + contextEnd - contextStart, flags, advances, advancesIndex, reserved); } @LayoutlibDelegate 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/src/libcore/icu/ICU_Delegate.java b/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java index e6dc646..98f8529 100644 --- a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java +++ b/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java @@ -44,6 +44,16 @@ public class ICU_Delegate { // --- Native methods accessing ICU's database. @LayoutlibDelegate + /*package*/ static String getIcuVersion() { + return "unknown_layoutlib"; + } + + @LayoutlibDelegate + /*package*/ static String getUnicodeVersion() { + return "5.2"; + } + + @LayoutlibDelegate /*package*/ static String[] getAvailableBreakIteratorLocalesNative() { return new String[0]; } @@ -74,17 +84,27 @@ public class ICU_Delegate { } @LayoutlibDelegate - /*package*/ static String getCurrencyCodeNative(String locale) { + /*package*/ static String[] getAvailableCurrencyCodes() { + return new String[0]; + } + + @LayoutlibDelegate + /*package*/ static String getCurrencyCode(String locale) { return ""; } @LayoutlibDelegate - /*package*/ static int getCurrencyFractionDigitsNative(String currencyCode) { + /*package*/ static String getCurrencyDisplayName(String locale, String currencyCode) { + return ""; + } + + @LayoutlibDelegate + /*package*/ static int getCurrencyFractionDigits(String currencyCode) { return 0; } @LayoutlibDelegate - /*package*/ static String getCurrencySymbolNative(String locale, String currencyCode) { + /*package*/ static String getCurrencySymbol(String locale, String currencyCode) { return ""; } @@ -114,6 +134,12 @@ public class ICU_Delegate { } @LayoutlibDelegate + /*package*/ static String addLikelySubtags(String locale) { + return ""; + } + + + @LayoutlibDelegate /*package*/ static String[] getISOLanguagesNative() { return Locale.getISOLanguages(); } diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java index 70d5446..96436fe 100644 --- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java +++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java @@ -16,14 +16,11 @@ package com.android.layoutlib.bridge.android; -import com.android.layoutlib.bridge.android.BridgeXmlBlockParser; +import com.android.layoutlib.bridge.impl.ParserFactory; -import org.kxml2.io.KXmlParser; import org.w3c.dom.Node; import org.xmlpull.v1.XmlPullParser; -import java.io.InputStream; - import junit.framework.TestCase; public class BridgeXmlBlockParserTest extends TestCase { @@ -39,12 +36,12 @@ public class BridgeXmlBlockParserTest extends TestCase { } public void testXmlBlockParser() throws Exception { - XmlPullParser parser = new KXmlParser(); - parser = new BridgeXmlBlockParser(parser, null, false /* platformResourceFlag */); - InputStream input = this.getClass().getClassLoader().getResourceAsStream( - "com/android/layoutlib/testdata/layout1.xml"); - parser.setInput(input, "UTF-8"); //$NON-NLS-1$ + XmlPullParser parser = ParserFactory.create( + getClass().getResourceAsStream("com/android/layoutlib/testdata/layout1.xml"), + "layout1.xml"); + + parser = new BridgeXmlBlockParser(parser, null, false /* platformResourceFlag */); assertEquals(XmlPullParser.START_DOCUMENT, parser.next()); diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java index 3df3736..4f5349a 100644 --- a/wifi/java/android/net/wifi/WifiStateMachine.java +++ b/wifi/java/android/net/wifi/WifiStateMachine.java @@ -1374,7 +1374,7 @@ public class WifiStateMachine extends StateMachine { intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | Intent.FLAG_RECEIVER_REPLACE_PENDING); intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, mNetworkInfo); - intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, mLinkProperties); + intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, new LinkProperties (mLinkProperties)); if (bssid != null) intent.putExtra(WifiManager.EXTRA_BSSID, bssid); mContext.sendStickyBroadcast(intent); @@ -1390,7 +1390,7 @@ public class WifiStateMachine extends StateMachine { private void sendLinkConfigurationChangedBroadcast() { Intent intent = new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); - intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, mLinkProperties); + intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, new LinkProperties(mLinkProperties)); mContext.sendBroadcast(intent); } @@ -1454,10 +1454,8 @@ public class WifiStateMachine extends StateMachine { Log.d(TAG, "Reset connections and stopping DHCP"); /* - * Reset connections & stop DHCP + * stop DHCP */ - NetworkUtils.resetConnections(mInterfaceName); - if (mDhcpStateMachine != null) { mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP); mDhcpStateMachine.quit(); @@ -1547,7 +1545,6 @@ public class WifiStateMachine extends StateMachine { if (!linkProperties.equals(mLinkProperties)) { Log.d(TAG, "Link configuration changed for netId: " + mLastNetworkId + " old: " + mLinkProperties + "new: " + linkProperties); - NetworkUtils.resetConnections(mInterfaceName); mLinkProperties = linkProperties; sendLinkConfigurationChangedBroadcast(); } @@ -2820,7 +2817,6 @@ public class WifiStateMachine extends StateMachine { if (mWifiInfo.getNetworkId() == result.getNetworkId()) { if (result.hasIpChanged()) { Log.d(TAG,"Reconfiguring IP on connection"); - NetworkUtils.resetConnections(mInterfaceName); transitionTo(mConnectingState); } if (result.hasProxyChanged()) { |