Merge "Add hide/show animations for action bar"
diff --git a/api/current.xml b/api/current.xml
index 708a852..b2c9f92 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -75700,6 +75700,16 @@
visibility="public"
>
</field>
+<field name="inPreferQualityOverSpeed"
+ type="boolean"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="inPreferredConfig"
type="android.graphics.Bitmap.Config"
transient="false"
@@ -184323,6 +184333,19 @@
<parameter name="gmtoff" type="long">
</parameter>
</method>
+<method name="getJulianMondayFromWeeksSinceEpoch"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="week" type="int">
+</parameter>
+</method>
<method name="getWeekNumber"
return="int"
abstract="false"
@@ -184334,6 +184357,21 @@
visibility="public"
>
</method>
+<method name="getWeeksSinceEpochFromJulianDay"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="julianDay" type="int">
+</parameter>
+<parameter name="firstDayOfWeek" type="int">
+</parameter>
+</method>
<method name="isEpoch"
return="boolean"
abstract="false"
@@ -184557,6 +184595,17 @@
visibility="public"
>
</field>
+<field name="MONDAY_BEFORE_JULIAN_EPOCH"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2440585"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="MONTH"
type="int"
transient="false"
@@ -198414,6 +198463,17 @@
visibility="public"
>
</field>
+<field name="FLAG_FALLBACK"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1024"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="FLAG_FROM_SYSTEM"
type="int"
transient="false"
@@ -198645,6 +198705,17 @@
visibility="public"
>
</field>
+<field name="KEYCODE_APP_SWITCH"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="187"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="KEYCODE_AT"
type="int"
transient="false"
@@ -227783,6 +227854,19 @@
visibility="public"
>
</method>
+<method name="removeJavascriptInterface"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="interfaceName" type="java.lang.String">
+</parameter>
+</method>
<method name="requestFocusNodeHref"
return="void"
abstract="false"
@@ -234469,7 +234553,7 @@
>
<parameter name="year" type="int">
</parameter>
-<parameter name="monthOfYear" type="int">
+<parameter name="month" type="int">
</parameter>
<parameter name="dayOfMonth" type="int">
</parameter>
@@ -234521,6 +234605,172 @@
</parameter>
</method>
</interface>
+<class name="DayPicker"
+ extends="android.widget.FrameLayout"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="DayPicker"
+ type="android.widget.DayPicker"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+</constructor>
+<constructor name="DayPicker"
+ type="android.widget.DayPicker"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="attrs" type="android.util.AttributeSet">
+</parameter>
+</constructor>
+<constructor name="DayPicker"
+ type="android.widget.DayPicker"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="attrs" type="android.util.AttributeSet">
+</parameter>
+<parameter name="defStyle" type="int">
+</parameter>
+</constructor>
+<method name="getSelectedDay"
+ return="java.util.Calendar"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="goTo"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="year" type="int">
+</parameter>
+<parameter name="month" type="int">
+</parameter>
+<parameter name="dayOfMonth" type="int">
+</parameter>
+<parameter name="animate" type="boolean">
+</parameter>
+<parameter name="setSelected" type="boolean">
+</parameter>
+<parameter name="forceScroll" type="boolean">
+</parameter>
+</method>
+<method name="goTo"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="date" type="java.util.Calendar">
+</parameter>
+<parameter name="animate" type="boolean">
+</parameter>
+<parameter name="setSelected" type="boolean">
+</parameter>
+<parameter name="forceScroll" type="boolean">
+</parameter>
+</method>
+<method name="setOnDateChangeListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.widget.DayPicker.OnSelectedDayChangeListener">
+</parameter>
+</method>
+<method name="setRange"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="startRangeDate" type="java.util.Calendar">
+</parameter>
+<parameter name="endRangeDate" type="java.util.Calendar">
+</parameter>
+</method>
+<method name="setSelectedDay"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="selectedDay" type="java.util.Calendar">
+</parameter>
+</method>
+</class>
+<interface name="DayPicker.OnSelectedDayChangeListener"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onSelectedDayChange"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="view" type="android.widget.DayPicker">
+</parameter>
+<parameter name="year" type="int">
+</parameter>
+<parameter name="month" type="int">
+</parameter>
+<parameter name="dayOfMonth" type="int">
+</parameter>
+</method>
+</interface>
<class name="DialerFilter"
extends="android.widget.RelativeLayout"
abstract="false"
@@ -239679,6 +239929,325 @@
</parameter>
</method>
</interface>
+<class name="NumberPicker"
+ extends="android.widget.LinearLayout"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="NumberPicker"
+ type="android.widget.NumberPicker"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+</constructor>
+<constructor name="NumberPicker"
+ type="android.widget.NumberPicker"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="attrs" type="android.util.AttributeSet">
+</parameter>
+</constructor>
+<constructor name="NumberPicker"
+ type="android.widget.NumberPicker"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="attrs" type="android.util.AttributeSet">
+</parameter>
+<parameter name="defStyle" type="int">
+</parameter>
+</constructor>
+<method name="getCurrent"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getRangeEnd"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getRangeStart"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="setCurrent"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="current" type="int">
+</parameter>
+</method>
+<method name="setFormatter"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="formatter" type="android.widget.NumberPicker.Formatter">
+</parameter>
+</method>
+<method name="setOnChangeListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="onChangeListener" type="android.widget.NumberPicker.OnChangeListener">
+</parameter>
+</method>
+<method name="setOnLongPressUpdateInterval"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="intervalMillis" type="long">
+</parameter>
+</method>
+<method name="setOnScrollListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="onScrollListener" type="android.widget.NumberPicker.OnScrollListener">
+</parameter>
+</method>
+<method name="setRange"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="start" type="int">
+</parameter>
+<parameter name="end" type="int">
+</parameter>
+</method>
+<method name="setRange"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="start" type="int">
+</parameter>
+<parameter name="end" type="int">
+</parameter>
+<parameter name="displayedValues" type="java.lang.String[]">
+</parameter>
+</method>
+<method name="setRange"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="start" type="int">
+</parameter>
+<parameter name="end" type="int">
+</parameter>
+<parameter name="displayedValues" type="java.lang.String[]">
+</parameter>
+<parameter name="wrapSelectorWheel" type="boolean">
+</parameter>
+</method>
+<method name="setWrapSelectorWheel"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="wrapSelector" type="boolean">
+</parameter>
+</method>
+<field name="TWO_DIGIT_FORMATTER"
+ type="android.widget.NumberPicker.Formatter"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<interface name="NumberPicker.Formatter"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="toString"
+ return="java.lang.String"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="value" type="int">
+</parameter>
+</method>
+</interface>
+<interface name="NumberPicker.OnChangeListener"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onChange"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="picker" type="android.widget.NumberPicker">
+</parameter>
+<parameter name="oldVal" type="int">
+</parameter>
+<parameter name="newVal" type="int">
+</parameter>
+</method>
+</interface>
+<interface name="NumberPicker.OnScrollListener"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onScrollStateChange"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="view" type="android.widget.NumberPicker">
+</parameter>
+<parameter name="scrollState" type="int">
+</parameter>
+</method>
+<field name="SCROLL_STATE_FLING"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCROLL_STATE_IDLE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCROLL_STATE_TOUCH_SCROLL"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</interface>
<class name="OverScroller"
extends="java.lang.Object"
abstract="false"
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 61ef8f2..a815b3a 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -838,6 +838,44 @@
}
}
+ void getAuthTokenLabel(final IAccountManagerResponse response,
+ final Account account, final String authTokenType) {
+ if (account == null) throw new IllegalArgumentException("account is null");
+ if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
+
+ checkBinderPermission(Manifest.permission.USE_CREDENTIALS);
+
+ long identityToken = clearCallingIdentity();
+ try {
+ new Session(response, account.type, false,
+ false /* stripAuthTokenFromResult */) {
+ protected String toDebugString(long now) {
+ return super.toDebugString(now) + ", getAuthTokenLabel"
+ + ", " + account
+ + ", authTokenType " + authTokenType;
+ }
+
+ public void run() throws RemoteException {
+ mAuthenticator.getAuthTokenLabel(this, authTokenType);
+ }
+
+ public void onResult(Bundle result) {
+ if (result != null) {
+ String label = result.getString(AccountManager.KEY_AUTH_TOKEN_LABEL);
+ Bundle bundle = new Bundle();
+ bundle.putString(AccountManager.KEY_AUTH_TOKEN_LABEL, label);
+ super.onResult(bundle);
+ return;
+ } else {
+ super.onResult(result);
+ }
+ }
+ }.bind();
+ } finally {
+ restoreCallingIdentity(identityToken);
+ }
+ }
+
public void getAuthToken(IAccountManagerResponse response, final Account account,
final String authTokenType, final boolean notifyOnAuthFailure,
final boolean expectActivityLaunch, final Bundle loginOptions) {
@@ -956,36 +994,36 @@
installNotification(getCredentialPermissionNotificationId(account, authTokenType, uid), n);
}
- private Intent newGrantCredentialsPermissionIntent(Account account, int uid,
- AccountAuthenticatorResponse response, String authTokenType, String authTokenLabel) {
+ String getAccountLabel(String accountType) {
RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo =
- mAuthenticatorCache.getServiceInfo(
- AuthenticatorDescription.newKey(account.type));
+ mAuthenticatorCache.getServiceInfo(
+ AuthenticatorDescription.newKey(accountType));
if (serviceInfo == null) {
- throw new IllegalArgumentException("unknown account type: " + account.type);
+ throw new IllegalArgumentException("unknown account type: " + accountType);
}
final Context authContext;
try {
authContext = mContext.createPackageContext(
- serviceInfo.type.packageName, 0);
+ serviceInfo.type.packageName, 0);
} catch (PackageManager.NameNotFoundException e) {
- throw new IllegalArgumentException("unknown account type: " + account.type);
+ throw new IllegalArgumentException("unknown account type: " + accountType);
}
+ return authContext.getString(serviceInfo.type.labelId);
+ }
+
+ private Intent newGrantCredentialsPermissionIntent(Account account, int uid,
+ AccountAuthenticatorResponse response, String authTokenType, String authTokenLabel) {
Intent intent = new Intent(mContext, GrantCredentialsPermissionActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addCategory(
String.valueOf(getCredentialPermissionNotificationId(account, authTokenType, uid)));
+
intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_ACCOUNT, account);
- intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_LABEL, authTokenLabel);
intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_TYPE, authTokenType);
intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_RESPONSE, response);
- intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_ACCOUNT_TYPE_LABEL,
- authContext.getString(serviceInfo.type.labelId));
- intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_PACKAGES,
- mPackageManager.getPackagesForUid(uid));
intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_REQUESTING_UID, uid);
+
return intent;
}
diff --git a/core/java/android/accounts/GrantCredentialsPermissionActivity.java b/core/java/android/accounts/GrantCredentialsPermissionActivity.java
index fd340cbe..83e4fd9 100644
--- a/core/java/android/accounts/GrantCredentialsPermissionActivity.java
+++ b/core/java/android/accounts/GrantCredentialsPermissionActivity.java
@@ -17,6 +17,7 @@
import android.app.Activity;
import android.os.Bundle;
+import android.os.RemoteException;
import android.widget.TextView;
import android.widget.LinearLayout;
import android.widget.ImageView;
@@ -26,6 +27,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.content.pm.RegisteredServicesCache;
import android.text.TextUtils;
import android.graphics.drawable.Drawable;
import com.android.internal.R;
@@ -46,6 +48,7 @@
private int mUid;
private Bundle mResultBundle = null;
protected LayoutInflater mInflater;
+ private final AccountManagerService accountManagerService = AccountManagerService.getSingleton();
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
@@ -55,27 +58,56 @@
mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final Bundle extras = getIntent().getExtras();
+
+ // Grant 'account'/'type' to mUID
mAccount = extras.getParcelable(EXTRAS_ACCOUNT);
mAuthTokenType = extras.getString(EXTRAS_AUTH_TOKEN_TYPE);
+ mUid = extras.getInt(EXTRAS_REQUESTING_UID);
+ final PackageManager pm = getPackageManager();
+ final String[] packages = pm.getPackagesForUid(mUid);
- if (mAccount == null || mAuthTokenType == null) {
+ if (mAccount == null || mAuthTokenType == null || packages == null) {
// we were somehow started with bad parameters. abort the activity.
setResult(Activity.RESULT_CANCELED);
finish();
return;
}
- mUid = extras.getInt(EXTRAS_REQUESTING_UID);
- final String accountTypeLabel = extras.getString(EXTRAS_ACCOUNT_TYPE_LABEL);
- final String[] packages = extras.getStringArray(EXTRAS_PACKAGES);
- final String authTokenLabel = extras.getString(EXTRAS_AUTH_TOKEN_LABEL);
+ final String accountTypeLabel = accountManagerService.getAccountLabel(mAccount.type);
+
+
+ final TextView authTokenTypeView = (TextView) findViewById(R.id.authtoken_type);
+ authTokenTypeView.setVisibility(View.GONE);
+
+ /** Handles the responses from the AccountManager */
+ IAccountManagerResponse response = new IAccountManagerResponse.Stub() {
+ public void onResult(Bundle bundle) {
+ final String authTokenLabel =
+ bundle.getString(AccountManager.KEY_AUTH_TOKEN_LABEL);
+ if (!TextUtils.isEmpty(authTokenLabel)) {
+ runOnUiThread(new Runnable() {
+ public void run() {
+ if (!isFinishing()) {
+ authTokenTypeView.setText(authTokenLabel);
+ authTokenTypeView.setVisibility(View.VISIBLE);
+ }
+ }
+ });
+ }
+ }
+
+ public void onError(int code, String message) {
+ }
+ };
+
+ accountManagerService.getAuthTokenLabel(
+ response, mAccount, mAuthTokenType);
findViewById(R.id.allow_button).setOnClickListener(this);
findViewById(R.id.deny_button).setOnClickListener(this);
LinearLayout packagesListView = (LinearLayout) findViewById(R.id.packages_list);
- final PackageManager pm = getPackageManager();
for (String pkg : packages) {
String packageLabel;
try {
@@ -88,12 +120,6 @@
((TextView) findViewById(R.id.account_name)).setText(mAccount.name);
((TextView) findViewById(R.id.account_type)).setText(accountTypeLabel);
- TextView authTokenTypeView = (TextView) findViewById(R.id.authtoken_type);
- if (TextUtils.isEmpty(authTokenLabel)) {
- authTokenTypeView.setVisibility(View.GONE);
- } else {
- authTokenTypeView.setText(authTokenLabel);
- }
}
private View newPackageView(String packageLabel) {
@@ -103,7 +129,6 @@
}
public void onClick(View v) {
- final AccountManagerService accountManagerService = AccountManagerService.getSingleton();
switch (v.getId()) {
case R.id.allow_button:
accountManagerService.grantAppPermission(mAccount, mAuthTokenType, mUid);
diff --git a/core/java/android/animation/PropertyValuesHolder.java b/core/java/android/animation/PropertyValuesHolder.java
index daef164..1412f38 100644
--- a/core/java/android/animation/PropertyValuesHolder.java
+++ b/core/java/android/animation/PropertyValuesHolder.java
@@ -325,7 +325,7 @@
// If we got here, then no appropriate function was found
Log.e("PropertyValuesHolder",
"Couldn't find setter/getter for property " + mPropertyName +
- "with value type "+ mValueType);
+ " with value type "+ mValueType);
}
return returnVal;
diff --git a/core/java/android/app/DatePickerDialog.java b/core/java/android/app/DatePickerDialog.java
index 37f8738..efe527f 100644
--- a/core/java/android/app/DatePickerDialog.java
+++ b/core/java/android/app/DatePickerDialog.java
@@ -16,23 +16,18 @@
package android.app;
+import com.android.internal.R;
+
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Build;
import android.os.Bundle;
-import android.text.TextUtils.TruncateAt;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.DatePicker;
-import android.widget.TextView;
import android.widget.DatePicker.OnDateChangedListener;
-import com.android.internal.R;
-
-import java.text.DateFormatSymbols;
-import java.util.Calendar;
-
/**
* A simple dialog containing an {@link android.widget.DatePicker}.
*
@@ -48,13 +43,6 @@
private final DatePicker mDatePicker;
private final OnDateSetListener mCallBack;
- private final Calendar mCalendar;
- private final java.text.DateFormat mTitleDateFormat;
- private final String[] mWeekDays;
-
- private int mInitialYear;
- private int mInitialMonth;
- private int mInitialDay;
/**
* The callback used to indicate the user is done filling in the date.
@@ -106,40 +94,18 @@
super(context, theme);
mCallBack = callBack;
- mInitialYear = year;
- mInitialMonth = monthOfYear;
- mInitialDay = dayOfMonth;
- DateFormatSymbols symbols = new DateFormatSymbols();
- mWeekDays = symbols.getShortWeekdays();
-
- mTitleDateFormat = java.text.DateFormat.
- getDateInstance(java.text.DateFormat.FULL);
- mCalendar = Calendar.getInstance();
- updateTitle(mInitialYear, mInitialMonth, mInitialDay);
setButton(BUTTON_POSITIVE, context.getText(R.string.date_time_set), this);
setButton(BUTTON_NEGATIVE, context.getText(R.string.cancel), (OnClickListener) null);
- setIcon(R.drawable.ic_dialog_time);
+ setIcon(0);
+ setTitle(R.string.date_picker_dialog_title);
LayoutInflater inflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.date_picker_dialog, null);
setView(view);
mDatePicker = (DatePicker) view.findViewById(R.id.datePicker);
- mDatePicker.init(mInitialYear, mInitialMonth, mInitialDay, this);
- }
-
- @Override
- public void show() {
- super.show();
-
- /* Sometimes the full month is displayed causing the title
- * to be very long, in those cases ensure it doesn't wrap to
- * 2 lines (as that looks jumpy) and ensure we ellipsize the end.
- */
- TextView title = (TextView) findViewById(R.id.alertTitle);
- title.setSingleLine();
- title.setEllipsize(TruncateAt.END);
+ mDatePicker.init(year, monthOfYear, dayOfMonth, this);
}
public void onClick(DialogInterface dialog, int which) {
@@ -152,23 +118,13 @@
public void onDateChanged(DatePicker view, int year,
int month, int day) {
- updateTitle(year, month, day);
+ mDatePicker.init(year, month, day, null);
}
public void updateDate(int year, int monthOfYear, int dayOfMonth) {
- mInitialYear = year;
- mInitialMonth = monthOfYear;
- mInitialDay = dayOfMonth;
mDatePicker.updateDate(year, monthOfYear, dayOfMonth);
}
- private void updateTitle(int year, int month, int day) {
- mCalendar.set(Calendar.YEAR, year);
- mCalendar.set(Calendar.MONTH, month);
- mCalendar.set(Calendar.DAY_OF_MONTH, day);
- setTitle(mTitleDateFormat.format(mCalendar.getTime()));
- }
-
@Override
public Bundle onSaveInstanceState() {
Bundle state = super.onSaveInstanceState();
@@ -185,6 +141,5 @@
int month = savedInstanceState.getInt(MONTH);
int day = savedInstanceState.getInt(DAY);
mDatePicker.init(year, month, day, this);
- updateTitle(year, month, day);
}
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 27be51a..b27f4cf 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -803,7 +803,7 @@
*
* @param intent The Intent to broadcast; all receivers matching this
* Intent will receive the broadcast.
- * @param receiverPermission (optional) String naming a permissions that
+ * @param receiverPermission (optional) String naming a permission that
* a receiver must hold in order to receive your broadcast.
* If null, no permission is required.
*
diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java
index ad05496..2f6b3a5 100644
--- a/core/java/android/nfc/Tag.java
+++ b/core/java/android/nfc/Tag.java
@@ -154,11 +154,7 @@
case TagTechnology.NFC_V: {
return new NfcV(adapter, this, extras);
}
- case TagTechnology.MIFARE_CLASSIC_NDEF:
- case TagTechnology.TYPE_1:
- case TagTechnology.TYPE_2:
- case TagTechnology.TYPE_3:
- case TagTechnology.TYPE_4: {
+ case TagTechnology.NDEF: {
return new Ndef(adapter, this, tech, extras);
}
case TagTechnology.NFC_F: {
diff --git a/core/java/android/nfc/technology/Ndef.java b/core/java/android/nfc/technology/Ndef.java
index 22460cf..1e3da2a 100644
--- a/core/java/android/nfc/technology/Ndef.java
+++ b/core/java/android/nfc/technology/Ndef.java
@@ -44,6 +44,9 @@
public static final int NDEF_MODE_WRITE_MANY = 4;
public static final int NDEF_MODE_UNKNOWN = 5;
+ /** @hide */
+ public static final String EXTRA_NDEF_MSG = "ndefmsg";
+
/**
* Internal constructor, to be used by NfcAdapter
* @hide
diff --git a/core/java/android/nfc/technology/TagTechnology.java b/core/java/android/nfc/technology/TagTechnology.java
index 9dfb297..4704f2b 100644
--- a/core/java/android/nfc/technology/TagTechnology.java
+++ b/core/java/android/nfc/technology/TagTechnology.java
@@ -49,22 +49,7 @@
/**
* This object is an instance of {@link Ndef}
*/
- public static final int TYPE_1 = 101;
-
- /**
- * This object is an instance of {@link Ndef}
- */
- public static final int TYPE_2 = 102;
-
- /**
- * This object is an instance of {@link Ndef}
- */
- public static final int TYPE_3 = 103;
-
- /**
- * This object is an instance of {@link Ndef}
- */
- public static final int TYPE_4 = 104;
+ public static final int NDEF = 101;
/**
* This object is an instance of {@link NdefFormatable}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index ed71da2..1e80da7 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -977,6 +977,9 @@
public static float getFloat(ContentResolver cr, String name)
throws SettingNotFoundException {
String v = getString(cr, name);
+ if (v == null) {
+ throw new SettingNotFoundException(name);
+ }
try {
return Float.parseFloat(v);
} catch (NumberFormatException e) {
@@ -1577,7 +1580,7 @@
* Default screen rotation when no other policy applies.
* When {@link #ACCELEROMETER_ROTATION} is zero and no on-screen Activity expresses a
* preference, this rotation value will be used. Must be one of the
- * {@link android.view.Surface#ROTATION_0 Surface rotation constants}.
+ * {@link android.view.Surface#ROTATION_0 Surface rotation constants}.
*
* @see Display#getRotation
*/
@@ -2296,6 +2299,9 @@
public static float getFloat(ContentResolver cr, String name)
throws SettingNotFoundException {
String v = getString(cr, name);
+ if (v == null) {
+ throw new SettingNotFoundException(name);
+ }
try {
return Float.parseFloat(v);
} catch (NumberFormatException e) {
diff --git a/core/java/android/text/format/Time.java b/core/java/android/text/format/Time.java
index c05a8fe..c6ffe58 100644
--- a/core/java/android/text/format/Time.java
+++ b/core/java/android/text/format/Time.java
@@ -42,6 +42,12 @@
public static final int EPOCH_JULIAN_DAY = 2440588;
/**
+ * The Julian day of the Monday in the week of the epoch, December 29, 1969
+ * on the Gregorian calendar.
+ */
+ public static final int MONDAY_BEFORE_JULIAN_EPOCH = EPOCH_JULIAN_DAY - 3;
+
+ /**
* True if this is an allDay event. The hour, minute, second fields are
* all zero, and the date is displayed the same in all time zones.
*/
@@ -770,4 +776,39 @@
millis = normalize(true);
return millis;
}
+
+ /**
+ * Returns the week since {@link #EPOCH_JULIAN_DAY} (Jan 1, 1970) adjusted
+ * for first day of week. This takes a julian day and the week start day and
+ * calculates which week since {@link #EPOCH_JULIAN_DAY} that day occurs in,
+ * starting at 0. *Do not* use this to compute the ISO week number for the
+ * year.
+ *
+ * @param julianDay The julian day to calculate the week number for
+ * @param firstDayOfWeek Which week day is the first day of the week, see
+ * {@link #SUNDAY}
+ * @return Weeks since the epoch
+ */
+ public static int getWeeksSinceEpochFromJulianDay(int julianDay, int firstDayOfWeek) {
+ int diff = THURSDAY - firstDayOfWeek;
+ if (diff < 0) {
+ diff += 7;
+ }
+ int refDay = EPOCH_JULIAN_DAY - diff;
+ return (julianDay - refDay) / 7;
+ }
+
+ /**
+ * Takes a number of weeks since the epoch and calculates the Julian day of
+ * the Monday for that week. This assumes that the week containing the
+ * {@link #EPOCH_JULIAN_DAY} is considered week 0. It returns the Julian day
+ * for the Monday week weeks after the Monday of the week containing the
+ * epoch.
+ *
+ * @param week Number of weeks since the epoch
+ * @return The julian day for the Monday of the given week since the epoch
+ */
+ public static int getJulianMondayFromWeeksSinceEpoch(int week) {
+ return MONDAY_BEFORE_JULIAN_EPOCH + week * 7;
+ }
}
diff --git a/core/java/android/view/KeyCharacterMap.java b/core/java/android/view/KeyCharacterMap.java
index 97bd8dd..5c4abd5 100644
--- a/core/java/android/view/KeyCharacterMap.java
+++ b/core/java/android/view/KeyCharacterMap.java
@@ -144,6 +144,8 @@
private static native void nativeDispose(int ptr);
private static native char nativeGetCharacter(int ptr, int keyCode, int metaState);
+ private static native boolean nativeGetFallbackAction(int ptr, int keyCode, int metaState,
+ FallbackAction outFallbackAction);
private static native char nativeGetNumber(int ptr, int keyCode);
private static native char nativeGetMatch(int ptr, int keyCode, char[] chars, int metaState);
private static native char nativeGetDisplayLabel(int ptr, int keyCode);
@@ -206,14 +208,9 @@
* @return The associated character or combining accent, or 0 if none.
*/
public int get(int keyCode, int metaState) {
- if ((metaState & MetaKeyKeyListener.META_CAP_LOCKED) != 0) {
- metaState |= KeyEvent.META_CAPS_LOCK_ON;
- }
- if ((metaState & MetaKeyKeyListener.META_ALT_LOCKED) != 0) {
- metaState |= KeyEvent.META_ALT_ON;
- }
-
+ metaState = applyLockedModifiers(metaState);
char ch = nativeGetCharacter(mPtr, keyCode, metaState);
+
int map = COMBINING.get(ch);
if (map != 0) {
return map;
@@ -223,6 +220,34 @@
}
/**
+ * Gets the fallback action to perform if the application does not
+ * handle the specified key.
+ * <p>
+ * When an application does not handle a particular key, the system may
+ * translate the key to an alternate fallback key (specified in the
+ * fallback action) and dispatch it to the application.
+ * The event containing the fallback key is flagged
+ * with {@link KeyEvent#FLAG_FALLBACK}.
+ * </p>
+ *
+ * @param keyCode The key code.
+ * @param metaState The meta key modifier state.
+ * @param outFallbackAction The fallback action object to populate.
+ * @return True if a fallback action was found, false otherwise.
+ *
+ * @hide
+ */
+ public boolean getFallbackAction(int keyCode, int metaState,
+ FallbackAction outFallbackAction) {
+ if (outFallbackAction == null) {
+ throw new IllegalArgumentException("fallbackAction must not be null");
+ }
+
+ metaState = applyLockedModifiers(metaState);
+ return nativeGetFallbackAction(mPtr, keyCode, metaState, outFallbackAction);
+ }
+
+ /**
* Gets the number or symbol associated with the key.
* <p>
* The character value is returned, not the numeric value.
@@ -277,6 +302,8 @@
if (chars == null) {
throw new IllegalArgumentException("chars must not be null.");
}
+
+ metaState = applyLockedModifiers(metaState);
return nativeGetMatch(mPtr, keyCode, chars, metaState);
}
@@ -509,6 +536,16 @@
return ret;
}
+ private static int applyLockedModifiers(int metaState) {
+ if ((metaState & MetaKeyKeyListener.META_CAP_LOCKED) != 0) {
+ metaState |= KeyEvent.META_CAPS_LOCK_ON;
+ }
+ if ((metaState & MetaKeyKeyListener.META_ALT_LOCKED) != 0) {
+ metaState |= KeyEvent.META_ALT_ON;
+ }
+ return metaState;
+ }
+
/**
* Maps Unicode combining diacritical to display-form dead key
* (display character shifted left 16 bits).
@@ -670,4 +707,14 @@
super(msg);
}
}
+
+ /**
+ * Specifies a substitute key code and meta state as a fallback action
+ * for an unhandled key.
+ * @hide
+ */
+ public static final class FallbackAction {
+ public int keyCode;
+ public int metaState;
+ }
}
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 03407a3..43b77e6 100755
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -529,15 +529,17 @@
/** Key code constant: Blue "programmable" key.
* On TV remotes, acts as a contextual/programmable key. */
public static final int KEYCODE_PROG_BLUE = 186;
+ /** Key code constant: App switch key.
+ * Should bring up the application switcher dialog. */
+ public static final int KEYCODE_APP_SWITCH = 187;
- private static final int LAST_KEYCODE = KEYCODE_PROG_BLUE;
+ private static final int LAST_KEYCODE = KEYCODE_APP_SWITCH;
// NOTE: If you add a new keycode here you must also add it to:
// isSystem()
// native/include/android/keycodes.h
// frameworks/base/include/ui/KeycodeLabels.h
// external/webkit/WebKit/android/plugins/ANPKeyCodes.h
- // tools/puppet_master/PuppetMaster/nav_keys.py
// frameworks/base/core/res/res/values/attrs.xml
// emulator?
//
@@ -737,6 +739,7 @@
"KEYCODE_PROG_GREEN",
"KEYCODE_PROG_YELLOW",
"KEYCODE_PROG_BLUE",
+ "KEYCODE_APP_SWITCH",
};
// Symbolic names of all metakeys in bit order from least significant to most significant.
@@ -1056,7 +1059,17 @@
* the tracking to be canceled.
*/
public static final int FLAG_TRACKING = 0x200;
-
+
+ /**
+ * Set when a key event has been synthesized to implement default behavior
+ * for an event that the application did not handle.
+ * Fallback key events are generated by unhandled trackball motions
+ * (to emulate a directional keypad) and by certain unhandled key presses
+ * that are declared in the key map (such as special function numeric keypad
+ * keys when numlock is off).
+ */
+ public static final int FLAG_FALLBACK = 0x400;
+
/**
* Private control to determine when an app is tracking a key sequence.
* @hide
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 1f5bb5d..ad96686 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -556,7 +556,7 @@
* improve the security of views that provide access to sensitive functionality.
* </p><p>
* To enable touch filtering, call {@link #setFilterTouchesWhenObscured} or set the
- * andoird:filterTouchesWhenObscured attribute to true. When enabled, the framework
+ * android:filterTouchesWhenObscured layout attribute to true. When enabled, the framework
* will discard touches that are received whenever the view's window is obscured by
* another visible window. As a result, the view will not receive touches whenever a
* toast, dialog or other window appears above the view's window.
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index a34fe87..9bda637 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -1101,7 +1101,9 @@
}
}
- if (hwInitialized || (windowShouldResize && mAttachInfo.mHardwareRenderer != null)) {
+ if (hwInitialized || (windowShouldResize &&
+ mAttachInfo.mHardwareRenderer != null &&
+ mAttachInfo.mHardwareRenderer.isEnabled())) {
mAttachInfo.mHardwareRenderer.setup(mWidth, mHeight);
}
@@ -2308,21 +2310,23 @@
}
final int action = event.getAction();
- final int metastate = event.getMetaState();
+ final int metaState = event.getMetaState();
switch (action) {
case MotionEvent.ACTION_DOWN:
x.reset(2);
y.reset(2);
deliverKeyEvent(new KeyEvent(curTime, curTime,
- KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_CENTER,
- 0, metastate), false);
+ KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_CENTER, 0, metaState,
+ KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FALLBACK,
+ InputDevice.SOURCE_KEYBOARD), false);
break;
case MotionEvent.ACTION_UP:
x.reset(2);
y.reset(2);
deliverKeyEvent(new KeyEvent(curTime, curTime,
- KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER,
- 0, metastate), false);
+ KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER, 0, metaState,
+ KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FALLBACK,
+ InputDevice.SOURCE_KEYBOARD), false);
break;
}
@@ -2372,9 +2376,11 @@
if (DEBUG_TRACKBALL) Log.v("foo", "Delivering fake DPAD: "
+ keycode);
movement--;
+ int repeatCount = accelMovement - movement;
deliverKeyEvent(new KeyEvent(curTime, curTime,
- KeyEvent.ACTION_MULTIPLE, keycode,
- accelMovement-movement, metastate), false);
+ KeyEvent.ACTION_MULTIPLE, keycode, repeatCount, metaState,
+ KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FALLBACK,
+ InputDevice.SOURCE_KEYBOARD), false);
}
while (movement > 0) {
if (DEBUG_TRACKBALL) Log.v("foo", "Delivering fake DPAD: "
@@ -2382,10 +2388,14 @@
movement--;
curTime = SystemClock.uptimeMillis();
deliverKeyEvent(new KeyEvent(curTime, curTime,
- KeyEvent.ACTION_DOWN, keycode, 0, event.getMetaState()), false);
+ KeyEvent.ACTION_DOWN, keycode, 0, metaState,
+ KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FALLBACK,
+ InputDevice.SOURCE_KEYBOARD), false);
deliverKeyEvent(new KeyEvent(curTime, curTime,
- KeyEvent.ACTION_UP, keycode, 0, metastate), false);
- }
+ KeyEvent.ACTION_UP, keycode, 0, metaState,
+ KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FALLBACK,
+ InputDevice.SOURCE_KEYBOARD), false);
+ }
mLastTrackballTime = curTime;
}
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index af36d80..3479bf5 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -587,9 +587,10 @@
* event will normally go.
* @param event The key event.
* @param policyFlags The policy flags associated with the key.
- * @return Returns true if the policy consumed the event.
+ * @return Returns an alternate key event to redispatch as a fallback, or null to give up.
+ * The caller is responsible for recycling the key event.
*/
- public boolean dispatchUnhandledKey(WindowState win, KeyEvent event, int policyFlags);
+ public KeyEvent dispatchUnhandledKey(WindowState win, KeyEvent event, int policyFlags);
/**
* Called when layout of the windows is about to start.
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index 8f92458..2c38c93 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -599,13 +599,20 @@
public void addJavascriptInterface(Object obj, String interfaceName) {
assert obj != null;
+ removeJavascriptInterface(interfaceName);
if (mJSInterfaceMap == null) {
mJSInterfaceMap = new HashMap<String, Object>();
}
+ mJSInterfaceMap.put(interfaceName, obj);
+ }
+
+ public void removeJavascriptInterface(String interfaceName) {
+ if (mJSInterfaceMap == null) {
+ return;
+ }
if (mJSInterfaceMap.containsKey(interfaceName)) {
mJSInterfaceMap.remove(interfaceName);
}
- mJSInterfaceMap.put(interfaceName, obj);
}
/**
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 44655ae..bf8f7db 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -3523,7 +3523,8 @@
* </ul></p>
* @param obj The class instance to bind to Javascript, null instances are
* ignored.
- * @param interfaceName The name to used to expose the class in JavaScript.
+ * @param interfaceName The name to used to expose the instance in
+ * JavaScript.
*/
public void addJavascriptInterface(Object obj, String interfaceName) {
if (obj == null) {
@@ -3536,6 +3537,16 @@
}
/**
+ * Removes a previously added JavaScript interface with the given name.
+ * @param interfaceName The name of the interface to remove.
+ */
+ public void removeJavascriptInterface(String interfaceName) {
+ WebViewCore.JSInterfaceData arg = new WebViewCore.JSInterfaceData();
+ arg.mInterfaceName = interfaceName;
+ mWebViewCore.sendMessage(EventHub.REMOVE_JS_INTERFACE, arg);
+ }
+
+ /**
* Return the WebSettings object used to control the settings for this
* WebView.
* @return A WebSettings object that can be used to control this WebView's
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index cc94fd0..d2c7fce 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -852,6 +852,7 @@
"VALID_NODE_BOUNDS", // = 146
"SAVE_WEBARCHIVE", // = 147
"WEBKIT_DRAW_LAYERS", // = 148;
+ "REMOVE_JS_INTERFACE", // = 149;
};
class EventHub {
@@ -925,6 +926,8 @@
// Update layers
static final int WEBKIT_DRAW_LAYERS = 148;
+ static final int REMOVE_JS_INTERFACE = 149;
+
// Network-based messaging
static final int CLEAR_SSL_PREF_TABLE = 150;
@@ -1290,6 +1293,12 @@
jsData.mInterfaceName);
break;
+ case REMOVE_JS_INTERFACE:
+ jsData = (JSInterfaceData) msg.obj;
+ mBrowserFrame.removeJavascriptInterface(
+ jsData.mInterfaceName);
+ break;
+
case REQUEST_EXT_REPRESENTATION:
mBrowserFrame.externalRepresentation(
(Message) msg.obj);
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index 595b487..4e5bc6e 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -16,6 +16,8 @@
package android.widget;
+import com.android.internal.R;
+
import android.annotation.Widget;
import android.content.Context;
import android.content.res.TypedArray;
@@ -26,50 +28,44 @@
import android.util.AttributeSet;
import android.util.SparseArray;
import android.view.LayoutInflater;
-import android.widget.NumberPicker;
-import android.widget.NumberPicker.OnChangedListener;
+import android.widget.NumberPicker.OnChangeListener;
-import com.android.internal.R;
-
-import java.text.DateFormatSymbols;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
/**
* A view for selecting a month / year / day based on a calendar like layout.
- *
- * <p>See the <a href="{@docRoot}resources/tutorials/views/hello-datepicker.html">Date Picker
- * tutorial</a>.</p>
- *
+ * <p>
+ * See the <a href="{@docRoot}
+ * resources/tutorials/views/hello-datepicker.html">Date Picker tutorial</a>.
+ * </p>
* For a dialog using this view, see {@link android.app.DatePickerDialog}.
*/
@Widget
public class DatePicker extends FrameLayout {
private static final int DEFAULT_START_YEAR = 1900;
+
private static final int DEFAULT_END_YEAR = 2100;
- // This ignores Undecimber, but we only support real Gregorian calendars.
- private static final int NUMBER_OF_MONTHS = 12;
-
- /* UI Components */
private final NumberPicker mDayPicker;
+
private final NumberPicker mMonthPicker;
+
private final NumberPicker mYearPicker;
- /**
- * How we notify users the date has changed.
- */
- private OnDateChangedListener mOnDateChangedListener;
-
- private int mDay;
- private int mMonth;
- private int mYear;
+ private final DayPicker mMiniMonthDayPicker;
- private Object mMonthUpdateLock = new Object();
- private volatile Locale mMonthLocale;
- private String[] mShortMonths;
+ private OnDateChangedListener mOnDateChangedListener;
+
+ private Locale mMonthLocale;
+
+ private final Calendar mTempCalendar = Calendar.getInstance();
+
+ private final int mNumberOfMonths = mTempCalendar.getActualMaximum(Calendar.MONTH) + 1;
+
+ private final String[] mShortMonths = new String[mNumberOfMonths];
/**
* The callback used to indicate the user changes the date.
@@ -80,7 +76,7 @@
* @param view The view associated with this listener.
* @param year The year that was set.
* @param monthOfYear The month that was set (0-11) for compatibility
- * with {@link java.util.Calendar}.
+ * with {@link java.util.Calendar}.
* @param dayOfMonth The day of the month that was set.
*/
void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth);
@@ -89,7 +85,7 @@
public DatePicker(Context context) {
this(context, null);
}
-
+
public DatePicker(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
@@ -97,103 +93,85 @@
public DatePicker(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
- LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ LayoutInflater inflater = (LayoutInflater) context
+ .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.date_picker, this, true);
+ OnChangeListener onChangeListener = new OnChangeListener() {
+ public void onChange(NumberPicker picker, int oldVal, int newVal) {
+ notifyDateChanged();
+ updateMiniMonth();
+ }
+ };
+
+ // day
mDayPicker = (NumberPicker) findViewById(R.id.day);
mDayPicker.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER);
- mDayPicker.setSpeed(100);
- mDayPicker.setOnChangeListener(new OnChangedListener() {
- public void onChanged(NumberPicker picker, int oldVal, int newVal) {
- mDay = newVal;
- notifyDateChanged();
- }
- });
+ mDayPicker.setOnLongPressUpdateInterval(100);
+ mDayPicker.setOnChangeListener(onChangeListener);
+
+ // month
mMonthPicker = (NumberPicker) findViewById(R.id.month);
- mMonthPicker.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER);
- final String[] months = getShortMonths();
+ mMonthPicker.setRange(0, mNumberOfMonths - 1, getShortMonths());
+ mMonthPicker.setOnLongPressUpdateInterval(200);
+ mMonthPicker.setOnChangeListener(onChangeListener);
- /*
- * If the user is in a locale where the month names are numeric,
- * use just the number instead of the "month" character for
- * consistency with the other fields.
- */
- if (months[0].startsWith("1")) {
- for (int i = 0; i < months.length; i++) {
- months[i] = String.valueOf(i + 1);
- }
- mMonthPicker.setRange(1, NUMBER_OF_MONTHS);
- } else {
- mMonthPicker.setRange(1, NUMBER_OF_MONTHS, months);
- }
-
- mMonthPicker.setSpeed(200);
- mMonthPicker.setOnChangeListener(new OnChangedListener() {
- public void onChanged(NumberPicker picker, int oldVal, int newVal) {
-
- /* We display the month 1-12 but store it 0-11 so always
- * subtract by one to ensure our internal state is always 0-11
- */
- mMonth = newVal - 1;
- // Adjust max day of the month
- adjustMaxDay();
- notifyDateChanged();
- updateDaySpinner();
- }
- });
+ // year
mYearPicker = (NumberPicker) findViewById(R.id.year);
- mYearPicker.setSpeed(100);
- mYearPicker.setOnChangeListener(new OnChangedListener() {
- public void onChanged(NumberPicker picker, int oldVal, int newVal) {
- mYear = newVal;
- // Adjust max day for leap years if needed
- adjustMaxDay();
- notifyDateChanged();
- updateDaySpinner();
- }
- });
-
- // attributes
+ mYearPicker.setOnLongPressUpdateInterval(100);
+ mYearPicker.setOnChangeListener(onChangeListener);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DatePicker);
-
int mStartYear = a.getInt(R.styleable.DatePicker_startYear, DEFAULT_START_YEAR);
int mEndYear = a.getInt(R.styleable.DatePicker_endYear, DEFAULT_END_YEAR);
mYearPicker.setRange(mStartYear, mEndYear);
-
a.recycle();
+
+ // mini-month day-picker
+ mMiniMonthDayPicker = (DayPicker) findViewById(R.id.mini_month_day_picker);
+ mTempCalendar.clear();
+ mTempCalendar.set(mStartYear, 0, 1);
+ Calendar endRangeDate = (Calendar) mTempCalendar.clone();
+ endRangeDate.set(mEndYear, 11, 31);
+ mMiniMonthDayPicker.setRange(mTempCalendar, endRangeDate);
+ mMiniMonthDayPicker.setOnDateChangeListener(new DayPicker.OnSelectedDayChangeListener() {
+ public void onSelectedDayChange(DayPicker view, int year, int month, int monthDay) {
+ updateDate(year, month, monthDay);
+ }
+ });
// initialize to current date
- Calendar cal = Calendar.getInstance();
- init(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), null);
-
+ mTempCalendar.setTimeInMillis(System.currentTimeMillis());
+ init(mTempCalendar.get(Calendar.YEAR), mTempCalendar.get(Calendar.MONTH),
+ mTempCalendar.get(Calendar.DAY_OF_MONTH), null);
+
// re-order the number pickers to match the current date format
- reorderPickers(months);
-
- if (!isEnabled()) {
- setEnabled(false);
- }
+ reorderPickers();
}
-
+
@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
mDayPicker.setEnabled(enabled);
mMonthPicker.setEnabled(enabled);
mYearPicker.setEnabled(enabled);
+ mMiniMonthDayPicker.setEnabled(enabled);
}
- private void reorderPickers(String[] months) {
+ /**
+ * Reorders the pickers according to the date format in the current locale.
+ */
+ private void reorderPickers() {
java.text.DateFormat format;
String order;
/*
- * If the user is in a locale where the medium date format is
- * still numeric (Japanese and Czech, for example), respect
- * the date format order setting. Otherwise, use the order
- * that the locale says is appropriate for a spelled-out date.
+ * If the user is in a locale where the medium date format is still
+ * numeric (Japanese and Czech, for example), respect the date format
+ * order setting. Otherwise, use the order that the locale says is
+ * appropriate for a spelled-out date.
*/
- if (months[0].startsWith("1")) {
+ if (getShortMonths()[0].startsWith("1")) {
format = DateFormat.getDateFormat(getContext());
} else {
format = DateFormat.getMediumDateFormat(getContext());
@@ -206,10 +184,11 @@
order = new String(DateFormat.getDateFormatOrder(getContext()));
}
- /* Remove the 3 pickers from their parent and then add them back in the
+ /*
+ * Remove the 3 pickers from their parent and then add them back in the
* required order.
*/
- LinearLayout parent = (LinearLayout) findViewById(R.id.parent);
+ LinearLayout parent = (LinearLayout) findViewById(R.id.pickers);
parent.removeAllViews();
boolean quoted = false;
@@ -230,7 +209,7 @@
parent.addView(mMonthPicker);
didMonth = true;
} else if (c == DateFormat.YEAR && !didYear) {
- parent.addView (mYearPicker);
+ parent.addView(mYearPicker);
didYear = true;
}
}
@@ -248,40 +227,145 @@
}
}
- public void updateDate(int year, int monthOfYear, int dayOfMonth) {
- if (mYear != year || mMonth != monthOfYear || mDay != dayOfMonth) {
- mYear = year;
- mMonth = monthOfYear;
- mDay = dayOfMonth;
- updateSpinners();
- reorderPickers(getShortMonths());
+ /**
+ * Updates the current date.
+ *
+ * @param year The year.
+ * @param month The month which is <strong>starting from zero</strong>.
+ * @param dayOfMonth The day of the month.
+ */
+ public void updateDate(int year, int month, int dayOfMonth) {
+ if (mYearPicker.getCurrent() != year
+ || mDayPicker.getCurrent() != dayOfMonth
+ || mMonthPicker.getCurrent() != month) {
+ updatePickers(year, month, dayOfMonth);
+ updateMiniMonth();
notifyDateChanged();
}
}
+ /**
+ * @return The short month abbreviations.
+ */
private String[] getShortMonths() {
final Locale currentLocale = Locale.getDefault();
- if (currentLocale.equals(mMonthLocale) && mShortMonths != null) {
+ if (currentLocale.equals(mMonthLocale)) {
return mShortMonths;
} else {
- synchronized (mMonthUpdateLock) {
- if (!currentLocale.equals(mMonthLocale)) {
- mShortMonths = new String[NUMBER_OF_MONTHS];
- for (int i = 0; i < NUMBER_OF_MONTHS; i++) {
- mShortMonths[i] = DateUtils.getMonthString(Calendar.JANUARY + i,
- DateUtils.LENGTH_MEDIUM);
- }
- mMonthLocale = currentLocale;
- }
+ for (int i = 0; i < mNumberOfMonths; i++) {
+ mShortMonths[i] = DateUtils.getMonthString(Calendar.JANUARY + i,
+ DateUtils.LENGTH_MEDIUM);
}
+ mMonthLocale = currentLocale;
return mShortMonths;
}
}
+ // Override so we are in complete control of save / restore for this widget.
+ @Override
+ protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
+ dispatchThawSelfOnly(container);
+ }
+
+ @Override
+ protected Parcelable onSaveInstanceState() {
+ Parcelable superState = super.onSaveInstanceState();
+ return new SavedState(superState, mYearPicker.getCurrent(), mMonthPicker.getCurrent(),
+ mDayPicker.getCurrent());
+ }
+
+ @Override
+ protected void onRestoreInstanceState(Parcelable state) {
+ SavedState ss = (SavedState) state;
+ super.onRestoreInstanceState(ss.getSuperState());
+ updatePickers(ss.mYear, ss.mMonth, ss.mDay);
+ }
+
+ /**
+ * Initialize the state. If the provided values designate an inconsistent
+ * date the values are normalized before updating the pickers.
+ *
+ * @param year The initial year.
+ * @param monthOfYear The initial month <strong>starting from zero</strong>.
+ * @param dayOfMonth The initial day of the month.
+ * @param onDateChangedListener How user is notified date is changed by
+ * user, can be null.
+ */
+ public void init(int year, int monthOfYear, int dayOfMonth,
+ OnDateChangedListener onDateChangedListener) {
+ mOnDateChangedListener = onDateChangedListener;
+ updateDate(year, monthOfYear, dayOfMonth);
+ }
+
+ /**
+ * Updates the pickers with the given <code>year</code>, <code>month</code>,
+ * and <code>dayOfMonth</code>. If the provided values designate an inconsistent
+ * date the values are normalized before updating the pickers.
+ */
+ private void updatePickers(int year, int month, int dayOfMonth) {
+ // make sure the date is normalized
+ mTempCalendar.clear();
+ mTempCalendar.set(year, month, dayOfMonth);
+ mYearPicker.setCurrent(mTempCalendar.get(Calendar.YEAR));
+ mMonthPicker.setCurrent(mTempCalendar.get(Calendar.MONTH));
+ mDayPicker.setRange(1, mTempCalendar.getActualMaximum(Calendar.DAY_OF_MONTH));
+ mDayPicker.setCurrent(mTempCalendar.get(Calendar.DAY_OF_MONTH));
+ }
+
+ /**
+ * Updates the mini-month with the given year, month, and day selected by the
+ * number pickers.
+ */
+ private void updateMiniMonth() {
+ Calendar selectedDay = mMiniMonthDayPicker.getSelectedDay();
+ if (selectedDay.get(Calendar.YEAR) != mYearPicker.getCurrent()
+ || selectedDay.get(Calendar.MONTH) != mMonthPicker.getCurrent()
+ || selectedDay.get(Calendar.DAY_OF_MONTH) != mDayPicker.getCurrent()) {
+ mMiniMonthDayPicker.goTo(mYearPicker.getCurrent(), mMonthPicker.getCurrent(),
+ mDayPicker.getCurrent(), false, true, false);
+ }
+ }
+
+ /**
+ * @return The selected year.
+ */
+ public int getYear() {
+ return mYearPicker.getCurrent();
+ }
+
+ /**
+ * @return The selected month.
+ */
+ public int getMonth() {
+ return mMonthPicker.getCurrent();
+ }
+
+ /**
+ * @return The selected day of month.
+ */
+ public int getDayOfMonth() {
+ return mDayPicker.getCurrent();
+ }
+
+ /**
+ * Notifies the listener, if such, for a change in the selected date.
+ */
+ private void notifyDateChanged() {
+ if (mOnDateChangedListener != null) {
+ mOnDateChangedListener.onDateChanged(DatePicker.this, mYearPicker.getCurrent(),
+ mMonthPicker.getCurrent(), mDayPicker.getCurrent());
+ }
+ }
+
+ /**
+ * Class for managing state storing/restoring.
+ */
private static class SavedState extends BaseSavedState {
private final int mYear;
+
private final int mMonth;
+
private final int mDay;
/**
@@ -293,7 +377,7 @@
mMonth = month;
mDay = day;
}
-
+
/**
* Constructor called from {@link #CREATOR}
*/
@@ -304,18 +388,6 @@
mDay = in.readInt();
}
- public int getYear() {
- return mYear;
- }
-
- public int getMonth() {
- return mMonth;
- }
-
- public int getDay() {
- return mDay;
- }
-
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
@@ -324,104 +396,17 @@
dest.writeInt(mDay);
}
- public static final Parcelable.Creator<SavedState> CREATOR =
- new Creator<SavedState>() {
+ @SuppressWarnings("all")
+ // suppress unused and hiding
+ public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() {
- public SavedState createFromParcel(Parcel in) {
- return new SavedState(in);
- }
+ public SavedState createFromParcel(Parcel in) {
+ return new SavedState(in);
+ }
- public SavedState[] newArray(int size) {
- return new SavedState[size];
- }
- };
- }
-
-
- /**
- * Override so we are in complete control of save / restore for this widget.
- */
- @Override
- protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
- dispatchThawSelfOnly(container);
- }
-
- @Override
- protected Parcelable onSaveInstanceState() {
- Parcelable superState = super.onSaveInstanceState();
-
- return new SavedState(superState, mYear, mMonth, mDay);
- }
-
- @Override
- protected void onRestoreInstanceState(Parcelable state) {
- SavedState ss = (SavedState) state;
- super.onRestoreInstanceState(ss.getSuperState());
- mYear = ss.getYear();
- mMonth = ss.getMonth();
- mDay = ss.getDay();
- updateSpinners();
- }
-
- /**
- * Initialize the state.
- * @param year The initial year.
- * @param monthOfYear The initial month.
- * @param dayOfMonth The initial day of the month.
- * @param onDateChangedListener How user is notified date is changed by user, can be null.
- */
- public void init(int year, int monthOfYear, int dayOfMonth,
- OnDateChangedListener onDateChangedListener) {
- mYear = year;
- mMonth = monthOfYear;
- mDay = dayOfMonth;
- mOnDateChangedListener = onDateChangedListener;
- updateSpinners();
- }
-
- private void updateSpinners() {
- updateDaySpinner();
- mYearPicker.setCurrent(mYear);
-
- /* The month display uses 1-12 but our internal state stores it
- * 0-11 so add one when setting the display.
- */
- mMonthPicker.setCurrent(mMonth + 1);
- }
-
- private void updateDaySpinner() {
- Calendar cal = Calendar.getInstance();
- cal.set(mYear, mMonth, mDay);
- int max = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
- mDayPicker.setRange(1, max);
- mDayPicker.setCurrent(mDay);
- }
-
- public int getYear() {
- return mYear;
- }
-
- public int getMonth() {
- return mMonth;
- }
-
- public int getDayOfMonth() {
- return mDay;
- }
-
- private void adjustMaxDay(){
- Calendar cal = Calendar.getInstance();
- cal.set(Calendar.YEAR, mYear);
- cal.set(Calendar.MONTH, mMonth);
- int max = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
- if (mDay > max) {
- mDay = max;
- }
- }
-
- private void notifyDateChanged() {
- if (mOnDateChangedListener != null) {
- mOnDateChangedListener.onDateChanged(DatePicker.this, mYear, mMonth, mDay);
- }
+ public SavedState[] newArray(int size) {
+ return new SavedState[size];
+ }
+ };
}
}
diff --git a/core/java/android/widget/DayPicker.java b/core/java/android/widget/DayPicker.java
new file mode 100644
index 0000000..11c23ab
--- /dev/null
+++ b/core/java/android/widget/DayPicker.java
@@ -0,0 +1,1474 @@
+/*
+ * 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 android.widget;
+
+import com.android.internal.R;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.database.DataSetObserver;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Paint.Align;
+import android.graphics.Paint.Style;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.text.format.DateFormat;
+import android.text.format.DateUtils;
+import android.text.format.Time;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.GestureDetector;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AbsListView.OnScrollListener;
+
+import java.security.InvalidParameterException;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Locale;
+
+import libcore.icu.LocaleData;
+
+/**
+ * Displays a day picker in the form of a calendar. The calendar
+ * is represented as a list where each row depicts a week. Each week is
+ * composed of items that are selectable days.
+ */
+public class DayPicker extends FrameLayout {
+
+ /**
+ * The number of milliseconds in a day.
+ *
+ * @hide
+ */
+ protected static final long MILLIS_IN_DAY = 86400000L;
+
+ /**
+ * The number of day in a week.
+ *
+ * @hide
+ */
+ protected static final int DAYS_PER_WEEK = 7;
+
+ /**
+ * The number of milliseconds in a week.
+ *
+ * @hide
+ */
+ protected static final long MILLIS_IN_WEEK = DAYS_PER_WEEK * MILLIS_IN_DAY;
+
+ /**
+ * Affects when the month selection will change while scrolling up
+ *
+ * @hide
+ */
+ protected static final int SCROLL_HYST_WEEKS = 2;
+
+ /**
+ * How long the GoTo fling animation should last.
+ *
+ * @hide
+ */
+ protected static final int GOTO_SCROLL_DURATION = 1000;
+
+ /**
+ * The duration of the adjustment upon a user scroll in milliseconds.
+ *
+ * @hide
+ */
+ protected static final int ADJUSTMENT_SCROLL_DURATION = 500;
+
+ /**
+ * How long to wait after receiving an onScrollStateChanged notification
+ * before acting on it.
+ *
+ * @hide
+ */
+ protected static final int SCROLL_CHANGE_DELAY = 40;
+
+ /**
+ * The scale used to compensate for different screen density.
+ *
+ * @hide
+ */
+ protected static float sScale;
+
+ /**
+ * The top offset of the weeks list.
+ *
+ * @hide
+ */
+ protected static int mListTopOffset = 2;
+
+ /**
+ * The visible height of a week view.
+ *
+ * @hide
+ */
+ protected int mWeekMinVisibleHeight = 12;
+
+
+ /**
+ * The visible height of a week view.
+ *
+ * @hide
+ */
+ protected int mBottomBuffer = 20;
+
+ /**
+ * The number of shown weeks.
+ *
+ * @hide
+ */
+ protected int mShownWeekCount = 6;
+
+ /**
+ * Flag whether to show the week number.
+ *
+ * @hide
+ */
+ protected boolean mShowWeekNumber = true;
+
+ /**
+ * The number of day per week to be shown
+ *
+ * @hide
+ */
+ protected int mDaysPerWeek = 7;
+
+ /**
+ * The friction of the week list while flinging.
+ *
+ * @hide
+ */
+ protected float mFriction = .05f;
+
+ /**
+ * Scale for adjusting velocity of the week list while flinging.
+ *
+ * @hide
+ */
+ protected float mVelocityScale = 0.333f;
+
+ /**
+ * The adapter for the weeks list.
+ *
+ * @hide
+ */
+ protected WeeksAdapter mAdapter;
+
+ /**
+ * The weeks list.
+ *
+ * @hide
+ */
+ protected ListView mListView;
+
+ /**
+ * The name of the month to display.
+ *
+ * @hide
+ */
+ protected TextView mMonthName;
+
+ /**
+ * The header with week day names.
+ *
+ * @hide
+ */
+ protected ViewGroup mDayNamesHeader;
+
+ /**
+ * Cached labels for the week names header.
+ *
+ * @hide
+ */
+ protected String[] mDayLabels;
+
+ /**
+ * Temporary instance to avoid multiple instantiations.
+ *
+ * @hide
+ */
+ protected Calendar mTempCalendar = Calendar.getInstance();
+
+ /**
+ * The first day of the week based on the current locale.
+ *
+ * @hide
+ */
+ protected int mFirstDayOfWeek = LocaleData.get(Locale.getDefault()).firstDayOfWeek;
+
+ /**
+ * The first day of the focused month.
+ *
+ * @hide
+ */
+ protected Calendar mFirstDayOfMonth = Calendar.getInstance();
+
+ /**
+ * Which month should be displayed/highlighted [0-11]
+ *
+ * @hide
+ */
+ protected int mCurrentMonthDisplayed;
+
+ /**
+ * Used for tracking during a scroll.
+ *
+ * @hide
+ */
+ protected long mPreviousScrollPosition;
+
+ /**
+ * Used for tracking which direction the view is scrolling.
+ *
+ * @hide
+ */
+ protected boolean mIsScrollingUp = false;
+
+ /**
+ * The previous scroll state of the weeks ListView.
+ *
+ * @hide
+ */
+ protected int mPreviousScrollState = OnScrollListener.SCROLL_STATE_IDLE;
+
+ /**
+ * The current scroll state of the weeks ListView.
+ *
+ * @hide
+ */
+ protected int mCurrentScrollState = OnScrollListener.SCROLL_STATE_IDLE;
+
+ /**
+ * Listener for changes in the selected day.
+ *
+ * @hide
+ */
+ protected OnSelectedDayChangeListener mOnChangeListener;
+
+ /**
+ * Command for adjusting the position after a scroll/fling.
+ *
+ * @hide
+ */
+ protected ScrollStateRunnable mScrollStateChangedRunnable = new ScrollStateRunnable();
+
+ /**
+ * The start date of the range supported by this picker.
+ *
+ * @hide
+ */
+ protected Calendar mStartRangeDate = Calendar.getInstance();
+
+ /**
+ * The end date of the range supported by this picker.
+ *
+ * @hide
+ */
+ protected Calendar mEndRangeDate = Calendar.getInstance();
+
+ /**
+ * String for formatting the month name in the title text view.
+ *
+ * @hide
+ */
+ protected String mMonthNameFormatSrting = "MMMM, yyyy";
+
+ /**
+ * The callback used to indicate the user changes the date.
+ */
+ public interface OnSelectedDayChangeListener {
+
+ /**
+ * Called upon change of the selected day.
+ *
+ * @param view The view associated with this listener.
+ * @param year The year that was set.
+ * @param month The month that was set [0-11].
+ * @param dayOfMonth The day of the month that was set.
+ */
+ public void onSelectedDayChange(DayPicker view, int year, int month, int dayOfMonth);
+ }
+
+ public DayPicker(Context context) {
+ this(context, null);
+ }
+
+ public DayPicker(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public DayPicker(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, 0);
+
+ LayoutInflater layoutInflater = (LayoutInflater) mContext
+ .getSystemService(Service.LAYOUT_INFLATER_SERVICE);
+ View content = layoutInflater.inflate(R.layout.day_picker, null, false);
+ addView(content);
+
+ mListView = (ListView) findViewById(R.id.list);
+ mDayNamesHeader = (ViewGroup) content.findViewById(com.android.internal.R.id.day_names);
+ mMonthName = (TextView) content.findViewById(com.android.internal.R.id.month_name);
+
+ // Adjust sizes for screen density
+ if (sScale == 0) {
+ sScale = mContext.getResources().getDisplayMetrics().density;
+ if (sScale != 1) {
+ mWeekMinVisibleHeight *= sScale;
+ mBottomBuffer *= sScale;
+ mListTopOffset *= sScale;
+ }
+ }
+
+ // set default range
+ mStartRangeDate.clear();
+ mStartRangeDate.set(1900, 0, 1);
+ mEndRangeDate.clear();
+ mEndRangeDate.set(2100, 0, 1);
+
+ setUpHeader();
+ updateHeader();
+ setUpListView();
+ setUpAdapter();
+
+ // go to today now
+ mTempCalendar.setTimeInMillis(System.currentTimeMillis());
+ goTo(mTempCalendar, false, true, true);
+ invalidate();
+ }
+
+ /**
+ * Sets the range supported by this day picker. This is the picker will not
+ * support dates before <code>startRangeDate</code> and <code>endRangeDate
+ * </code>.
+ *
+ * @param startRangeDate The start date.
+ * @param endRangeDate The end date.
+ */
+ public void setRange(Calendar startRangeDate, Calendar endRangeDate) {
+ boolean doSetupAdapter = false;
+ if (mStartRangeDate.get(Calendar.DAY_OF_YEAR) != startRangeDate.get(Calendar.DAY_OF_YEAR)
+ || mStartRangeDate.get(Calendar.YEAR) != startRangeDate.get(Calendar.YEAR)) {
+ mStartRangeDate = startRangeDate;
+ doSetupAdapter = true;
+ }
+ if (mEndRangeDate.get(Calendar.DAY_OF_YEAR) != endRangeDate.get(Calendar.DAY_OF_YEAR)
+ || mEndRangeDate.get(Calendar.YEAR) != endRangeDate.get(Calendar.YEAR)) {
+ mEndRangeDate = endRangeDate;
+ doSetupAdapter = true;
+
+ }
+ if (doSetupAdapter) {
+ setUpAdapter();
+ }
+ }
+
+ /**
+ * Sets the listener to be notified upon day selection changes.
+ *
+ * @param listener The listener to be called back.
+ */
+ public void setOnDateChangeListener(OnSelectedDayChangeListener listener) {
+ mOnChangeListener = listener;
+ }
+
+ /**
+ * Gets the selected day.
+ *
+ * @return The selected day.
+ */
+ public Calendar getSelectedDay() {
+ return mAdapter.mSelectedDay;
+ }
+
+ /**
+ * Sets the selected day. This is equivalent to a call to
+ * {@link #goTo(Calendar, boolean, boolean, boolean)} with
+ * the arguments <code>selectedDay</code>, <code>false</code>,
+ * <code>true</code>, <code>false</code> respectively.
+ *
+ * @param selectedDay The selected day.
+ */
+ public void setSelectedDay(Calendar selectedDay) {
+ goTo(selectedDay, false, true, false);
+ }
+
+ /**
+ * Creates a new adapter if necessary and sets up its parameters. Override
+ * this method to provide a custom adapter.
+ *
+ * @hide
+ */
+ protected void setUpAdapter() {
+ if (mAdapter == null) {
+ mAdapter = new WeeksAdapter(getContext());
+ mAdapter.registerDataSetObserver(new DataSetObserver() {
+ @Override
+ public void onChanged() {
+ if (mOnChangeListener != null) {
+ Calendar selectedDay = mAdapter.getSelectedDay();
+ mOnChangeListener.onSelectedDayChange(DayPicker.this,
+ selectedDay.get(Calendar.YEAR),
+ selectedDay.get(Calendar.MONTH),
+ selectedDay.get(Calendar.DAY_OF_MONTH));
+ }
+ }
+ });
+ mListView.setAdapter(mAdapter);
+ }
+
+ // refresh the view with the new parameters
+ mAdapter.notifyDataSetChanged();
+ }
+
+ /**
+ * Sets up the strings to be used by the header. Override this method to use
+ * different strings or modify the view params.
+ *
+ * @hide
+ */
+ protected void setUpHeader() {
+ mDayLabels = new String[mDaysPerWeek];
+ for (int i = mFirstDayOfWeek, count = mFirstDayOfWeek + mDaysPerWeek; i < count; i++) {
+ int calendarDay = (i < mDaysPerWeek) ? i : 1; // Calendar.MONDAY is
+ // 1
+ mDayLabels[i - mFirstDayOfWeek] = DateUtils.getDayOfWeekString(calendarDay,
+ DateUtils.LENGTH_SHORTEST);
+ }
+ }
+
+ /**
+ * Sets all the required fields for the list view. Override this method to
+ * set a different list view behavior.
+ *
+ * @hide
+ */
+ protected void setUpListView() {
+ // Configure the listview
+ mListView.setDivider(null);
+ mListView.setItemsCanFocus(true);
+ mListView.setVerticalScrollBarEnabled(false);
+ mListView.setOnScrollListener(new OnScrollListener() {
+ public void onScrollStateChanged(AbsListView view, int scrollState) {
+ DayPicker.this.onScrollStateChanged(view, scrollState);
+ }
+
+ public void onScroll(
+ AbsListView view, int firstVisibleItem, int visibleItemCount,
+ int totalItemCount) {
+ DayPicker.this.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
+ }
+ });
+ // Make the scrolling behavior nicer
+ mListView.setFriction(mFriction);
+ mListView.setVelocityScale(mVelocityScale);
+ }
+
+ /**
+ * Fixes the day names header to provide correct spacing and updates the
+ * label text. Override this to set up a custom header.
+ *
+ * @hide
+ */
+ protected void updateHeader() {
+ TextView label = (TextView) mDayNamesHeader.getChildAt(0);
+ if (mShowWeekNumber) {
+ label.setVisibility(View.VISIBLE);
+ } else {
+ label.setVisibility(View.GONE);
+ }
+ for (int i = 1, count = mDayNamesHeader.getChildCount(); i < count; i++) {
+ label = (TextView) mDayNamesHeader.getChildAt(i);
+ if (i < mDaysPerWeek + 1) {
+ label.setText(mDayLabels[i - 1]);
+ label.setVisibility(View.VISIBLE);
+ } else {
+ label.setVisibility(View.GONE);
+ }
+ }
+ mDayNamesHeader.invalidate();
+ }
+
+ /**
+ * This moves to the specified time in the view. If the time is not already
+ * in range it will move the list so that the first of the month containing
+ * the time is at the top of the view. If the new time is already in view
+ * the list will not be scrolled unless forceScroll is true. This time may
+ * optionally be highlighted as selected as well.
+ *
+ * @param year The year to move to.
+ * @param month The month to move to <strong>starting from zero<strong>.
+ * @param dayOfMonth The month day to move to.
+ * @param animate Whether to scroll to the given time or just redraw at the
+ * new location.
+ * @param setSelected Whether to set the given time as selected
+ * @param forceScroll Whether to recenter even if the time is already
+ * visible.
+ */
+ public void goTo(int year, int month, int dayOfMonth, boolean animate, boolean setSelected,
+ boolean forceScroll) {
+ mTempCalendar.clear();
+ mTempCalendar.set(year, month, dayOfMonth);
+ goTo(mTempCalendar, animate, setSelected, forceScroll);
+ }
+
+ /**
+ * This moves to the specified time in the view. If the time is not already
+ * in range it will move the list so that the first of the month containing
+ * the time is at the top of the view. If the new time is already in view
+ * the list will not be scrolled unless forceScroll is true. This time may
+ * optionally be highlighted as selected as well.
+ *
+ * @param date The time to move to.
+ * @param animate Whether to scroll to the given time or just redraw at the
+ * new location.
+ * @param setSelected Whether to set the given time as selected.
+ * @param forceScroll Whether to recenter even if the time is already
+ * visible.
+ */
+ public void goTo(Calendar date, boolean animate, boolean setSelected, boolean forceScroll) {
+ long timeInMillis = date.getTimeInMillis();
+ if (timeInMillis < mStartRangeDate.getTimeInMillis()
+ || timeInMillis > mEndRangeDate.getTimeInMillis()) {
+ throw new IllegalArgumentException("Time not between " + mStartRangeDate.getTime()
+ + " and " + mEndRangeDate.getTime());
+ }
+ // Find the first and last entirely visible weeks
+ int firstFullyVisiblePosition = mListView.getFirstVisiblePosition();
+ View firstChild = mListView.getChildAt(0);
+ if (firstChild != null && firstChild.getTop() < 0) {
+ firstFullyVisiblePosition++;
+ }
+ int lastFullyVisiblePosition = firstFullyVisiblePosition + mShownWeekCount - 1;
+ if (firstChild != null && firstChild.getTop() > mBottomBuffer) {
+ lastFullyVisiblePosition--;
+ }
+ if (setSelected) {
+ mAdapter.setSelectedDay(date);
+ }
+ // Get the week we're going to
+ int position = getWeeksDelta(date);
+
+ // Check if the selected day is now outside of our visible range
+ // and if so scroll to the month that contains it
+ if (position < firstFullyVisiblePosition || position > lastFullyVisiblePosition
+ || forceScroll) {
+ mFirstDayOfMonth.setTimeInMillis(date.getTimeInMillis());
+ mFirstDayOfMonth.setTimeZone(date.getTimeZone());
+ mFirstDayOfMonth.set(Calendar.DAY_OF_MONTH, 1);
+
+ setMonthDisplayed(mFirstDayOfMonth);
+ position = getWeeksDelta(mFirstDayOfMonth);
+
+ mPreviousScrollState = OnScrollListener.SCROLL_STATE_FLING;
+ if (animate) {
+ mListView.smoothScrollToPositionFromTop(position, mListTopOffset,
+ GOTO_SCROLL_DURATION);
+ } else {
+ mListView.setSelectionFromTop(position, mListTopOffset);
+ // Perform any after scroll operations that are needed
+ onScrollStateChanged(mListView, OnScrollListener.SCROLL_STATE_IDLE);
+ }
+ } else if (setSelected) {
+ // Otherwise just set the selection
+ setMonthDisplayed(date);
+ }
+ }
+
+ /**
+ * Called when a <code>view</code> transitions to a new <code>scrollState
+ * </code>.
+ *
+ * @hide
+ */
+ protected void onScrollStateChanged(AbsListView view, int scrollState) {
+ mScrollStateChangedRunnable.doScrollStateChange(view, scrollState);
+ }
+
+ /**
+ * Updates the title and selected month if the <code>view</code> has moved to a new
+ * month.
+ *
+ * @hide
+ */
+ protected void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
+ int totalItemCount) {
+ WeekView child = (WeekView) view.getChildAt(0);
+ if (child == null) {
+ return;
+ }
+
+ // Figure out where we are
+ int offset = child.getBottom() < mWeekMinVisibleHeight ? 1 : 0;
+ long currScroll = view.getFirstVisiblePosition() * child.getHeight() - child.getBottom();
+
+ // If we have moved since our last call update the direction
+ if (currScroll < mPreviousScrollPosition) {
+ mIsScrollingUp = true;
+ } else if (currScroll > mPreviousScrollPosition) {
+ mIsScrollingUp = false;
+ } else {
+ return;
+ }
+
+ // Use some hysteresis for checking which month to highlight. This
+ // causes the month to transition when two full weeks of a month are
+ // visible when scrolling up, and when the first day in a month reaches
+ // the top of the screen when scrolling down.
+ if (mIsScrollingUp) {
+ child = (WeekView) view.getChildAt(SCROLL_HYST_WEEKS + offset);
+ } else if (offset != 0) {
+ child = (WeekView) view.getChildAt(offset);
+ }
+
+ // Find out which month we're moving into
+ int month;
+ if (mIsScrollingUp) {
+ month = child.getMonthOfFirstWeekDay();
+ } else {
+ month = child.getMonthOfLastWeekDay();
+ }
+
+ // And how it relates to our current highlighted month
+ int monthDiff;
+ if (mCurrentMonthDisplayed == 11 && month == 0) {
+ monthDiff = 1;
+ } else if (mCurrentMonthDisplayed == 0 && month == 11) {
+ monthDiff = -1;
+ } else {
+ monthDiff = month - mCurrentMonthDisplayed;
+ }
+
+ // Only switch months if we're scrolling away from the currently
+ // selected month
+ if ((!mIsScrollingUp && monthDiff > 0) || (mIsScrollingUp && monthDiff < 0)) {
+ Calendar firstDay = child.getFirstDay();
+ if (mIsScrollingUp) {
+ firstDay.add(Calendar.DAY_OF_MONTH, -DAYS_PER_WEEK);
+ } else {
+ firstDay.add(Calendar.DAY_OF_MONTH, DAYS_PER_WEEK);
+ }
+ setMonthDisplayed(firstDay);
+ }
+ mPreviousScrollPosition = currScroll;
+ mPreviousScrollState = mCurrentScrollState;
+ }
+
+ /**
+ * Sets the month displayed at the top of this view based on time. Override
+ * to add custom events when the title is changed.
+ *
+ * @param calendar A day in the new focus month.
+ *
+ * @hide
+ */
+ protected void setMonthDisplayed(Calendar calendar) {
+ mMonthName.setText(DateFormat.format(mMonthNameFormatSrting, calendar));
+ mMonthName.invalidate();
+ mCurrentMonthDisplayed = calendar.get(Calendar.MONTH);
+ mAdapter.setFocusMonth(mCurrentMonthDisplayed);
+ // TODO Send Accessibility Event
+ }
+
+ /**
+ * @return Returns the number of weeks between the current week day of the
+ * <code>fromDate</code> and the first day of week of
+ * <code>toDate</code>.
+ *
+ * @hide
+ */
+ protected int getWeeksDelta(Calendar toDate) {
+ if (toDate.before(mStartRangeDate)) {
+ throw new IllegalArgumentException("fromDate: " + mStartRangeDate.getTime()
+ + " does not precede toDate: " + toDate.getTime());
+ }
+ int fromDateDayOfWeek = mStartRangeDate.get(Calendar.DAY_OF_WEEK);
+ long diff = (fromDateDayOfWeek - toDate.getFirstDayOfWeek()) * MILLIS_IN_DAY;
+ if (diff < 0) {
+ diff = diff + MILLIS_IN_WEEK;
+ }
+ long refDay = mStartRangeDate.getTimeInMillis() - diff;
+ return (int) ((toDate.getTimeInMillis() - refDay) / MILLIS_IN_WEEK);
+ }
+
+ /**
+ * Command responsible for acting upon scroll state changes.
+ *
+ * @hide
+ */
+ protected class ScrollStateRunnable implements Runnable {
+ private AbsListView mView;
+
+ private int mNewState;
+
+ /**
+ * Sets up the runnable with a short delay in case the scroll state
+ * immediately changes again.
+ *
+ * @param view The list view that changed state
+ * @param scrollState The new state it changed to
+ */
+ public void doScrollStateChange(AbsListView view, int scrollState) {
+ removeCallbacks(this);
+ mView = view;
+ mNewState = scrollState;
+ removeCallbacks(this);
+ postDelayed(this, SCROLL_CHANGE_DELAY);
+ }
+
+ public void run() {
+ mCurrentScrollState = mNewState;
+ // Fix the position after a scroll or a fling ends
+ if (mNewState == OnScrollListener.SCROLL_STATE_IDLE
+ && mPreviousScrollState != OnScrollListener.SCROLL_STATE_IDLE) {
+ mPreviousScrollState = mNewState;
+ View child = mView.getChildAt(0);
+ if (child == null) {
+ // The view is no longer visible, just return
+ return;
+ }
+ int dist = child.getBottom() - mListTopOffset;
+ if (dist > mListTopOffset) {
+ if (mIsScrollingUp) {
+ mView.smoothScrollBy(dist - child.getHeight(), ADJUSTMENT_SCROLL_DURATION);
+ } else {
+ mView.smoothScrollBy(dist, ADJUSTMENT_SCROLL_DURATION);
+ }
+ }
+ } else {
+ mPreviousScrollState = mNewState;
+ }
+ }
+ }
+
+ /**
+ * <p>
+ * This is a specialized adapter for creating a list of weeks with
+ * selectable days. It can be configured to display the week number, start
+ * the week on a given day, show a reduced number of days, or display an
+ * arbitrary number of weeks at a time.
+ * </p>
+ *
+ * @hide
+ */
+ public class WeeksAdapter extends BaseAdapter implements OnTouchListener {
+
+ /**
+ * The default maximum year supported by the Date Time Picker.
+ */
+ public static final int DEFAULT_MAX_CALENDAR_YEAR = 2100;
+
+ /**
+ * The default minimum year supported by the Date Time Picker.
+ */
+ public static final int DEFAULT_MIN_CALENDAR_YEAR = 1900;
+
+ /**
+ * The number of weeks to display at a time.
+ */
+ public static final String WEEK_PARAMS_NUM_WEEKS = "num_weeks";
+
+ /**
+ * Which month should be in focus currently.
+ */
+ public static final String WEEK_PARAMS_FOCUS_MONTH = "focus_month";
+
+ /**
+ * Whether the week number should be shown. Non-zero to show them.
+ */
+ public static final String WEEK_PARAMS_SHOW_WEEK = "week_numbers";
+
+ /**
+ * Which day the week should start on. {@link Time#SUNDAY} through
+ * {@link Time#SATURDAY}.
+ */
+ public static final String WEEK_PARAMS_WEEK_START = "week_start";
+
+ /**
+ * The year of the highlighted day.
+ */
+ public static final String WEEK_PARAMS_YEAR = "selected_year";
+
+ /**
+ * The month of the highlighted day.
+ */
+ public static final String WEEK_PARAMS_MONTH = "selected_month";
+
+ /**
+ * The year of the highlighted day.
+ */
+ public static final String WEEK_PARAMS_DAY_OF_MONTH = "selected_day_of_month";
+
+ /**
+ * The start date of the supported interval.
+ */
+ public static final String WEEK_PARAMS_START_DATE_RANGE_MILLIS = "start_date_gange_millis";
+
+ /**
+ * The end date of the supported interval.
+ */
+ public static final String WEEK_PARAMS_END_DATE_RANGE_MILLIS = "end_date_gange_millis";
+
+ /**
+ * How many days of the week to display [1-7].
+ */
+ public static final String WEEK_PARAMS_DAYS_PER_WEEK = "days_per_week";
+
+ protected int WEEK_7_OVERHANG_HEIGHT = 7;
+
+ protected int mSelectedWeek;
+
+ protected GestureDetector mGestureDetector;
+
+ protected int mFocusMonth = 0;
+
+ private final Calendar mSelectedDay = Calendar.getInstance();
+
+ private int mTotalWeekCount = -1;
+
+ public WeeksAdapter(Context context) {
+ mContext = context;
+
+ if (sScale == 0) {
+ sScale = context.getResources().getDisplayMetrics().density;
+ if (sScale != 1) {
+ WEEK_7_OVERHANG_HEIGHT *= sScale;
+ }
+ }
+ init();
+ }
+
+ /**
+ * Set up the gesture detector and selected time
+ */
+ protected void init() {
+ mGestureDetector = new GestureDetector(mContext, new CalendarGestureListener());
+ mSelectedWeek = getWeeksDelta(mSelectedDay);
+ mTotalWeekCount = getWeeksDelta(mEndRangeDate);
+ }
+
+ /**
+ * Updates the selected day and related parameters.
+ *
+ * @param selectedDay The time to highlight
+ */
+ public void setSelectedDay(Calendar selectedDay) {
+ if (selectedDay.get(Calendar.DAY_OF_YEAR) == mSelectedDay.get(Calendar.DAY_OF_YEAR)
+ && selectedDay.get(Calendar.YEAR) == mSelectedDay.get(Calendar.YEAR)) {
+ return;
+ }
+ mSelectedDay.setTimeInMillis(selectedDay.getTimeInMillis());
+ mSelectedDay.setTimeZone(selectedDay.getTimeZone());
+ mSelectedWeek = getWeeksDelta(mSelectedDay);
+ mFocusMonth = mSelectedDay.get(Calendar.MONTH);
+ notifyDataSetChanged();
+ invalidate(); // Test
+ }
+
+ /**
+ * @return The selected day of month.
+ */
+ public Calendar getSelectedDay() {
+ return mSelectedDay;
+ }
+
+ /**
+ * updates any config options that may have changed and refreshes the
+ * view
+ */
+ public void refresh() {
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public int getCount() {
+ return mTotalWeekCount;
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return null;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ WeekView v;
+ HashMap<String, Object> drawingParams = null;
+ if (convertView != null) {
+ v = (WeekView) convertView;
+ // We store the drawing parameters in the view so it can be
+ // recycled
+ drawingParams = (HashMap<String, Object>) v.getTag();
+ } else {
+ v = getNewView();
+ // Set up the new view
+ android.widget.AbsListView.LayoutParams params =
+ new android.widget.AbsListView.LayoutParams(
+ LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+ v.setLayoutParams(params);
+ v.setClickable(true);
+ v.setOnTouchListener(this);
+
+ drawingParams = new HashMap<String, Object>();
+ }
+
+ // pass in all the view parameters
+ putDrawingParementer(drawingParams, WeekView.VIEW_PARAMS_SHOW_WK_NUM,
+ mShowWeekNumber ? 1 : 0);
+ putDrawingParementer(drawingParams, WeekView.VIEW_PARAMS_WEEK_START, mFirstDayOfWeek);
+ putDrawingParementer(drawingParams, WeekView.VIEW_PARAMS_NUM_DAYS, mDaysPerWeek);
+ putDrawingParementer(drawingParams, WeekView.VIEW_PARAMS_WEEK, position);
+ putDrawingParementer(drawingParams, WeekView.VIEW_PARAMS_FOCUS_MONTH, mFocusMonth);
+ putDrawingParementer(drawingParams, WeekView.VIEW_PARAMS_SELECTED_DAY,
+ (mSelectedWeek == position) ? mSelectedDay.get(Calendar.DAY_OF_WEEK) : -1);
+ v.setWeekParams(drawingParams);
+
+ return v;
+ }
+
+ /**
+ * Puts the given <code>value</code> for the drawing
+ * <code>parameter</code> in the <code>drawingParams</code>.
+ */
+ private void putDrawingParementer(HashMap<String, Object> drawingParams, String parameter,
+ int value) {
+ int[] valueArray = (int[]) drawingParams.get(parameter);
+ if (valueArray == null) {
+ valueArray = new int[1];
+ drawingParams.put(parameter, valueArray);
+ }
+ valueArray[0] = value;
+ }
+
+ /**
+ * Creates a new WeekView and returns it. Override this to customize the
+ * view creation.
+ *
+ * @return A new WeekView
+ */
+ protected WeekView getNewView() {
+ return new WeekView(mContext);
+ }
+
+ /**
+ * Changes which month is in focus and updates the view.
+ *
+ * @param month The month to show as in focus [0-11]
+ */
+ public void setFocusMonth(int month) {
+ if (mFocusMonth == month) {
+ return;
+ }
+ mFocusMonth = month;
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ if (mGestureDetector.onTouchEvent(event)) {
+ WeekView weekView = (WeekView) v;
+ weekView.getDayFromLocation(event.getX(), mTempCalendar);
+ if (mTempCalendar.get(Calendar.YEAR) != 0) {
+ onDayTapped(mTempCalendar);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Maintains the same hour/min/sec but moves the day to the tapped day.
+ *
+ * @param day The day that was tapped
+ */
+ protected void onDayTapped(Calendar day) {
+ setSelectedDay(day);
+ }
+
+ /**
+ * This is here so we can identify single tap events and set the
+ * selected day correctly
+ */
+ protected class CalendarGestureListener extends GestureDetector.SimpleOnGestureListener {
+ @Override
+ public boolean onSingleTapUp(MotionEvent e) {
+ return true;
+ }
+ }
+ }
+
+ /**
+ * <p>
+ * This is a dynamic view for drawing a single week. It can be configured to
+ * display the week number, start the week on a given day, or show a reduced
+ * number of days. It is intended for use as a single view within a
+ * ListView. See {@link WeeksAdapter} for usage.
+ * </p>
+ *
+ * @hide
+ */
+ public class WeekView extends View {
+
+ /*
+ * These params can be passed into the view to control how it appears.
+ * {@link #VIEW_PARAMS_WEEK} is the only required field, though the
+ * default values are unlikely to fit most layouts correctly.
+ */
+
+ /**
+ * This sets the height of this week in pixels
+ */
+ public static final String VIEW_PARAMS_HEIGHT = "height";
+
+ /**
+ * This specifies the position (or weeks since the epoch) of this week.
+ */
+ public static final String VIEW_PARAMS_WEEK = "week";
+
+ /**
+ * This sets one of the days in this view as selected
+ * {@link Time#SUNDAY} through {@link Time#SATURDAY}.
+ */
+ public static final String VIEW_PARAMS_SELECTED_DAY = "selected_day";
+
+ /**
+ * Which day the week should start on. {@link Time#SUNDAY} through
+ * {@link Time#SATURDAY}.
+ */
+ public static final String VIEW_PARAMS_WEEK_START = "week_start";
+
+ /**
+ * How many days to display at a time. Days will be displayed starting
+ * with {@link #mFirstDay}.
+ */
+ public static final String VIEW_PARAMS_NUM_DAYS = "num_days";
+
+ /**
+ * Which month is currently in focus, as defined by {@link Time#month}
+ * [0-11].
+ */
+ public static final String VIEW_PARAMS_FOCUS_MONTH = "focus_month";
+
+ /**
+ * If this month should display week numbers. false if 0, true
+ * otherwise.
+ */
+ public static final String VIEW_PARAMS_SHOW_WK_NUM = "show_wk_num";
+
+ protected int mDefaultHeight = 32;
+
+ protected int mMinHeight = 10;
+
+ protected static final int DEFAULT_SELECTED_DAY = -1;
+
+ protected static final int DEFAULT_WEEK_START = Calendar.SUNDAY;
+
+ protected static final int DEFAULT_NUM_DAYS = 7;
+
+ protected static final int DEFAULT_SHOW_WK_NUM = 0;
+
+ protected static final int DEFAULT_FOCUS_MONTH = -1;
+
+ protected static final int DAY_SEPARATOR_WIDTH = 1;
+
+ protected int mNumberTextSize = 14;
+
+ // affects the padding on the sides of this view
+ protected int mPadding = 0;
+
+ protected final Rect mTempRect = new Rect();
+
+ protected final Paint mDrawPaint = new Paint();
+
+ protected Paint mMonthNumDrawPaint = new Paint();
+
+ protected Drawable mSelectedDayLine;
+
+ protected final int mSelectionBackgroundColor;
+
+ protected final int mFocusedMonthDateColor;
+
+ protected final int mOtherMonthDateColor;
+
+ protected final int mGridLinesColor;
+
+ protected final int mWeekNumberColor;
+
+ // Cache the number strings so we don't have to recompute them each time
+ protected String[] mDayNumbers;
+
+ // Quick lookup for checking which days are in the focus month
+ protected boolean[] mFocusDay;
+
+ // The first day displayed by this item
+ protected Calendar mFirstDay;
+
+ // The month of the first day in this week
+ protected int mMonthOfFirstWeekDay = -1;
+
+ // The month of the last day in this week
+ protected int mLastWeekDayMonth = -1;
+
+ // The position of this week, equivalent to weeks since the week of Jan
+ // 1st, 1900
+ protected int mWeek = -1;
+
+ // Quick reference to the width of this view, matches parent
+ protected int mWidth;
+
+ // The height this view should draw at in pixels, set by height param
+ protected int mHeight = mDefaultHeight;
+
+ // Whether the week number should be shown
+ protected boolean mShowWeekNum = false;
+
+ // If this view contains the selected day
+ protected boolean mHasSelectedDay = false;
+
+ // Which day is selected [0-6] or -1 if no day is selected
+ protected int mSelectedDay = DEFAULT_SELECTED_DAY;
+
+ // How many days to display
+ protected int mNumDays = DEFAULT_NUM_DAYS;
+
+ // The number of days + a spot for week number if it is displayed
+ protected int mNumCells = mNumDays;
+
+ // The left edge of the selected day
+ protected int mSelectedLeft = -1;
+
+ // The right edge of the selected day
+ protected int mSelectedRight = -1;
+
+ public WeekView(Context context) {
+ super(context);
+
+ TypedValue outTypedValue = new TypedValue();
+ context.getTheme().resolveAttribute(R.attr.dayPickerWeekViewStyle, outTypedValue, true);
+ TypedArray attributesArray = context.obtainStyledAttributes(outTypedValue.resourceId,
+ R.styleable.DayPickerWeekView);
+
+ mSelectionBackgroundColor = attributesArray.getColor(
+ R.styleable.DayPickerWeekView_selectionBackgroundColor, 0);
+ mFocusedMonthDateColor = attributesArray.getColor(
+ R.styleable.DayPickerWeekView_focusedMonthDateColor, 0);
+ mOtherMonthDateColor = attributesArray.getColor(
+ R.styleable.DayPickerWeekView_otherMonthDateColor, 0);
+ mGridLinesColor = attributesArray.getColor(
+ R.styleable.DayPickerWeekView_gridLinesColor, 0);
+ mWeekNumberColor = attributesArray.getColor(
+ R.styleable.DayPickerWeekView_weekNumberColor, 0);
+ mSelectedDayLine = attributesArray
+ .getDrawable(R.styleable.DayPickerWeekView_selectedDayLine);
+ attributesArray.recycle();
+
+ if (sScale == 0) {
+ sScale = context.getResources().getDisplayMetrics().density;
+ if (sScale != 1) {
+ mDefaultHeight *= sScale;
+ mMinHeight *= sScale;
+ mNumberTextSize *= sScale;
+ }
+ }
+
+ // Sets up any standard paints that will be used
+ setPaintProperties();
+ }
+
+ /**
+ * Sets all the parameters for displaying this week. The only required
+ * parameter is the week number. Other parameters have a default value
+ * and will only update if a new value is included, except for focus
+ * month, which will always default to no focus month if no value is
+ * passed in. See {@link #VIEW_PARAMS_HEIGHT} for more info on
+ * parameters.
+ *
+ * @param params A map of the new parameters, see
+ * {@link #VIEW_PARAMS_HEIGHT}
+ */
+ public void setWeekParams(HashMap<String, Object> params) {
+ if (!params.containsKey(VIEW_PARAMS_WEEK)) {
+ throw new InvalidParameterException(
+ "You must specify the week number for this view");
+ }
+ setTag(params);
+ // We keep the current value for any params not present
+ if (params.containsKey(VIEW_PARAMS_HEIGHT)) {
+ mHeight = ((int[]) params.get(VIEW_PARAMS_HEIGHT))[0];
+ if (mHeight < mMinHeight) {
+ mHeight = mMinHeight;
+ }
+ }
+ if (params.containsKey(VIEW_PARAMS_SELECTED_DAY)) {
+ mSelectedDay = ((int[]) params.get(VIEW_PARAMS_SELECTED_DAY))[0];
+ }
+ mHasSelectedDay = mSelectedDay != -1;
+ if (params.containsKey(VIEW_PARAMS_NUM_DAYS)) {
+ mNumDays = ((int[]) params.get(VIEW_PARAMS_NUM_DAYS))[0];
+ }
+ if (params.containsKey(VIEW_PARAMS_SHOW_WK_NUM)) {
+ if (((int[]) params.get(VIEW_PARAMS_SHOW_WK_NUM))[0] != 0) {
+ mNumCells = mNumDays + 1;
+ mShowWeekNum = true;
+ } else {
+ mShowWeekNum = false;
+ }
+ } else {
+ mNumCells = mShowWeekNum ? mNumDays + 1 : mNumDays;
+ }
+ mWeek = ((int[]) params.get(VIEW_PARAMS_WEEK))[0];
+ mTempCalendar.clear();
+ mTempCalendar.set(1900, 0, 1);
+ mTempCalendar.add(Calendar.WEEK_OF_YEAR, mWeek);
+ if (params.containsKey(VIEW_PARAMS_WEEK_START)) {
+ mTempCalendar.setFirstDayOfWeek(((int[]) params.get(VIEW_PARAMS_WEEK_START))[0]);
+ } else {
+ mTempCalendar.setFirstDayOfWeek(DEFAULT_WEEK_START);
+ }
+
+ // Allocate space for caching the day numbers and focus values
+ mDayNumbers = new String[mNumCells];
+ mFocusDay = new boolean[mNumCells];
+
+ // If we're showing the week number calculate it based on Monday
+ int i = 0;
+ if (mShowWeekNum) {
+ mDayNumbers[0] = Integer.toString(mTempCalendar.get(Calendar.WEEK_OF_YEAR));
+ i++;
+ }
+
+ // Now adjust our starting day based on the start day of the week
+ int diff = mTempCalendar.getFirstDayOfWeek() - mTempCalendar.get(Calendar.DAY_OF_WEEK);
+ mTempCalendar.add(Calendar.DAY_OF_MONTH, diff);
+
+ mFirstDay = (Calendar) mTempCalendar.clone();
+
+ mMonthOfFirstWeekDay = mTempCalendar.get(Calendar.MONTH);
+
+ int focusMonth = params.containsKey(VIEW_PARAMS_FOCUS_MONTH) ? ((int[]) params
+ .get(VIEW_PARAMS_FOCUS_MONTH))[0] : DEFAULT_FOCUS_MONTH;
+
+ for (; i < mNumCells; i++) {
+ mFocusDay[i] = (mTempCalendar.get(Calendar.MONTH) == focusMonth);
+ mDayNumbers[i] = Integer.toString(mTempCalendar.get(Calendar.DAY_OF_MONTH));
+ mTempCalendar.add(Calendar.DAY_OF_MONTH, 1);
+ }
+ // We do one extra add at the end of the loop, if that pushed us to
+ // new month undo it
+ if (mTempCalendar.get(Calendar.DAY_OF_MONTH) == 1) {
+ mTempCalendar.add(Calendar.DAY_OF_MONTH, -1);
+ }
+ mLastWeekDayMonth = mTempCalendar.get(Calendar.MONTH);
+
+ updateSelectionPositions();
+ }
+
+ /**
+ * Sets up the text and style properties for painting. Override this if
+ * you want to use a different paint.
+ */
+ protected void setPaintProperties() {
+ mDrawPaint.setFakeBoldText(false);
+ mDrawPaint.setAntiAlias(true);
+ mDrawPaint.setTextSize(mNumberTextSize);
+ mDrawPaint.setStyle(Style.FILL);
+
+ mMonthNumDrawPaint.setFakeBoldText(true);
+ mMonthNumDrawPaint.setAntiAlias(true);
+ mMonthNumDrawPaint.setTextSize(mNumberTextSize);
+ mMonthNumDrawPaint.setColor(mFocusedMonthDateColor);
+ mMonthNumDrawPaint.setStyle(Style.FILL);
+ mMonthNumDrawPaint.setTextAlign(Align.CENTER);
+ }
+
+ /**
+ * Returns the month of the first day in this week.
+ *
+ * @return The month the first day of this view is in.
+ */
+ public int getMonthOfFirstWeekDay() {
+ return mMonthOfFirstWeekDay;
+ }
+
+ /**
+ * Returns the month of the last day in this week
+ *
+ * @return The month the last day of this view is in
+ */
+ public int getMonthOfLastWeekDay() {
+ return mLastWeekDayMonth;
+ }
+
+ /**
+ * Returns the first day in this view.
+ *
+ * @return The first day in the view.
+ */
+ public Calendar getFirstDay() {
+ return mFirstDay;
+ }
+
+ /**
+ * Returns the number of days this view will display.
+ */
+ public int getNumDays() {
+ return mNumDays;
+ }
+
+ /**
+ * Calculates the day that the given x position is in, accounting for
+ * week number. Returns a Time referencing that day or null if
+ *
+ * @param x The x position of the touch eventy
+ */
+ public void getDayFromLocation(float x, Calendar outCalendar) {
+ int dayStart = mShowWeekNum ? (mWidth - mPadding * 2) / mNumCells + mPadding : mPadding;
+ if (x < dayStart || x > mWidth - mPadding) {
+ outCalendar.set(0, 0, 0, 0, 0, 0);
+ return;
+ }
+ // Selection is (x - start) / (pixels/day) == (x -s) * day / pixels
+ int dayPosition = (int) ((x - dayStart) * mNumDays / (mWidth - dayStart - mPadding));
+ outCalendar.setTimeZone(mFirstDay.getTimeZone());
+ outCalendar.setTimeInMillis(mFirstDay.getTimeInMillis());
+ outCalendar.add(Calendar.DAY_OF_MONTH, dayPosition);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ drawBackground(canvas);
+ drawWeekNums(canvas);
+ drawDaySeparators(canvas);
+ }
+
+ /**
+ * This draws the selection highlight if a day is selected in this week.
+ * Override this method if you wish to have a different background
+ * drawn.
+ *
+ * @param canvas The canvas to draw on
+ */
+ protected void drawBackground(Canvas canvas) {
+ if (!mHasSelectedDay) {
+ return;
+ }
+ mDrawPaint.setColor(mSelectionBackgroundColor);
+
+ mTempRect.top = DAY_SEPARATOR_WIDTH;
+ mTempRect.bottom = mHeight;
+ mTempRect.left = mShowWeekNum ? mPadding + (mWidth - mPadding * 2) / mNumCells
+ : mPadding;
+ mTempRect.right = mSelectedLeft - 2;
+ canvas.drawRect(mTempRect, mDrawPaint);
+
+ mTempRect.left = mSelectedRight + 3;
+ mTempRect.right = mWidth - mPadding;
+ canvas.drawRect(mTempRect, mDrawPaint);
+ }
+
+ /**
+ * Draws the week and month day numbers for this week. Override this
+ * method if you need different placement.
+ *
+ * @param canvas The canvas to draw on
+ */
+ protected void drawWeekNums(Canvas canvas) {
+ float textHeight = mDrawPaint.getTextSize();
+ int y = (int) ((mHeight + textHeight) / 2) - DAY_SEPARATOR_WIDTH;
+ int nDays = mNumCells;
+
+ mDrawPaint.setTextAlign(Align.CENTER);
+ int i = 0;
+ int divisor = 2 * nDays;
+ if (mShowWeekNum) {
+ mDrawPaint.setColor(mWeekNumberColor);
+ int x = (mWidth - mPadding * 2) / divisor + mPadding;
+ canvas.drawText(mDayNumbers[0], x, y, mDrawPaint);
+ i++;
+ }
+ for (; i < nDays; i++) {
+ mMonthNumDrawPaint.setColor(mFocusDay[i] ? mFocusedMonthDateColor
+ : mOtherMonthDateColor);
+ int x = (2 * i + 1) * (mWidth - mPadding * 2) / divisor + mPadding;
+ canvas.drawText(mDayNumbers[i], x, y, mMonthNumDrawPaint);
+ }
+ }
+
+ /**
+ * Draws a horizontal line for separating the weeks. Override this
+ * method if you want custom separators.
+ *
+ * @param canvas The canvas to draw on
+ */
+ protected void drawDaySeparators(Canvas canvas) {
+ mDrawPaint.setColor(mGridLinesColor);
+ mDrawPaint.setStrokeWidth(DAY_SEPARATOR_WIDTH);
+ float x = mShowWeekNum ? mPadding + (mWidth - mPadding * 2) / mNumCells : mPadding;
+ canvas.drawLine(x, 0, mWidth - mPadding, 0, mDrawPaint);
+
+ if (mHasSelectedDay) {
+ mSelectedDayLine.setBounds(mSelectedLeft - 2, DAY_SEPARATOR_WIDTH,
+ mSelectedLeft + 4, mHeight + 1);
+ mSelectedDayLine.draw(canvas);
+ mSelectedDayLine.setBounds(mSelectedRight - 3, DAY_SEPARATOR_WIDTH,
+ mSelectedRight + 3, mHeight + 1);
+ mSelectedDayLine.draw(canvas);
+ }
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ mWidth = w;
+ updateSelectionPositions();
+ }
+
+ /**
+ * This calculates the positions for the selected day lines.
+ */
+ protected void updateSelectionPositions() {
+ if (mHasSelectedDay) {
+ int selectedPosition = mSelectedDay - mTempCalendar.getFirstDayOfWeek();
+ if (selectedPosition < 0) {
+ selectedPosition += 7;
+ }
+ if (mShowWeekNum) {
+ selectedPosition++;
+ }
+ mSelectedLeft = selectedPosition * (mWidth - mPadding * 2) / mNumCells + mPadding;
+ mSelectedRight = (selectedPosition + 1) * (mWidth - mPadding * 2) / mNumCells
+ + mPadding;
+ }
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), mHeight);
+ }
+ }
+}
diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java
index 940fec1..26e191d 100644
--- a/core/java/android/widget/FrameLayout.java
+++ b/core/java/android/widget/FrameLayout.java
@@ -76,6 +76,8 @@
boolean mForegroundBoundsChanged = false;
+ private static final int DEFAULT_CHILD_GRAVITY = Gravity.TOP | Gravity.LEFT;
+
public FrameLayout(Context context) {
super(context);
}
@@ -307,41 +309,42 @@
int childLeft = parentLeft;
int childTop = parentTop;
- final int gravity = lp.gravity;
+ int gravity = lp.gravity;
+ if (gravity == -1) {
+ gravity = DEFAULT_CHILD_GRAVITY;
+ }
- if (gravity != -1) {
- final int horizontalGravity = gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
- final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
+ final int horizontalGravity = gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
+ final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
- switch (horizontalGravity) {
- case Gravity.LEFT:
- childLeft = parentLeft + lp.leftMargin;
- break;
- case Gravity.CENTER_HORIZONTAL:
- childLeft = parentLeft + (parentRight - parentLeft - width) / 2 +
- lp.leftMargin - lp.rightMargin;
- break;
- case Gravity.RIGHT:
- childLeft = parentRight - width - lp.rightMargin;
- break;
- default:
- childLeft = parentLeft + lp.leftMargin;
- }
+ switch (horizontalGravity) {
+ case Gravity.LEFT:
+ childLeft = parentLeft + lp.leftMargin;
+ break;
+ case Gravity.CENTER_HORIZONTAL:
+ childLeft = parentLeft + (parentRight - parentLeft - width) / 2 +
+ lp.leftMargin - lp.rightMargin;
+ break;
+ case Gravity.RIGHT:
+ childLeft = parentRight - width - lp.rightMargin;
+ break;
+ default:
+ childLeft = parentLeft + lp.leftMargin;
+ }
- switch (verticalGravity) {
- case Gravity.TOP:
- childTop = parentTop + lp.topMargin;
- break;
- case Gravity.CENTER_VERTICAL:
- childTop = parentTop + (parentBottom - parentTop - height) / 2 +
- lp.topMargin - lp.bottomMargin;
- break;
- case Gravity.BOTTOM:
- childTop = parentBottom - height - lp.bottomMargin;
- break;
- default:
- childTop = parentTop + lp.topMargin;
- }
+ switch (verticalGravity) {
+ case Gravity.TOP:
+ childTop = parentTop + lp.topMargin;
+ break;
+ case Gravity.CENTER_VERTICAL:
+ childTop = parentTop + (parentBottom - parentTop - height) / 2 +
+ lp.topMargin - lp.bottomMargin;
+ break;
+ case Gravity.BOTTOM:
+ childTop = parentBottom - height - lp.bottomMargin;
+ break;
+ default:
+ childTop = parentTop + lp.topMargin;
}
child.layout(childLeft, childTop, childLeft + width, childTop + height);
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index c05e3ad..50867b9 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -1420,8 +1420,8 @@
final int height = getHeight();
canvas.rotate(270);
- canvas.translate(-height * 1.5f, Math.min(0, scrollX));
- mEdgeGlowLeft.setSize(getHeight() * 2, getWidth());
+ canvas.translate(-height, Math.min(0, scrollX));
+ mEdgeGlowLeft.setSize(getHeight(), getWidth());
if (mEdgeGlowLeft.draw(canvas)) {
invalidate();
}
@@ -1433,8 +1433,9 @@
final int height = getHeight();
canvas.rotate(90);
- canvas.translate(-height / 2, -(Math.max(getScrollRange(), scrollX) + width));
- mEdgeGlowRight.setSize(height * 2, width);
+ canvas.translate(0,
+ -(Math.max(getScrollRange(), scrollX) + width));
+ mEdgeGlowRight.setSize(height, width);
if (mEdgeGlowRight.draw(canvas)) {
invalidate();
}
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 43d194f..805bc08 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -30,8 +30,8 @@
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
-import android.graphics.Rect;
import android.graphics.Paint.Align;
+import android.graphics.Rect;
import android.text.InputFilter;
import android.text.InputType;
import android.text.Spanned;
@@ -41,19 +41,27 @@
import android.util.SparseArray;
import android.view.KeyEvent;
import android.view.LayoutInflater;
+import android.view.LayoutInflater.Filter;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
-import android.view.LayoutInflater.Filter;
import android.view.animation.OvershootInterpolator;
import android.view.inputmethod.InputMethodManager;
/**
- * A view for selecting a number For a dialog using this view, see
- * {@link android.app.TimePickerDialog}.
- *
- * @hide
+ * A widget that enables the user to select a number form a predefined range.
+ * The widget presents an input filed and up and down buttons for selecting the
+ * current value. Pressing/long pressing the up and down buttons increments and
+ * decrements the current value respectively. Touching the input filed shows a
+ * scroll wheel, tapping on which while shown and not moving allows direct edit
+ * of the current value. Sliding motions up or down hide the buttons and the
+ * input filed, show the scroll wheel, and rotate the latter. Flinging is
+ * also supported. The widget enables mapping from positions to strings such
+ * that instead the position index the corresponding string is displayed.
+ * <p>
+ * For an example of using this widget, see {@link android.widget.TimePicker}.
+ * </p>
*/
@Widget
public class NumberPicker extends LinearLayout {
@@ -166,7 +174,12 @@
/**
* Listener to be notified upon current value change.
*/
- private OnChangedListener mListener;
+ private OnChangeListener mOnChangeListener;
+
+ /**
+ * Listener to be notified upon scroll state change.
+ */
+ private OnScrollListener mOnScrollListener;
/**
* Formatter for for displaying the current value.
@@ -176,7 +189,7 @@
/**
* The speed for updating the value form long press.
*/
- private long mLongPressUpdateSpeed = 300;
+ private long mLongPressUpdateInterval = 300;
/**
* Cache for the string representation of selector indices.
@@ -308,26 +321,79 @@
private final Rect mTempRect = new Rect();
/**
+ * The current scroll state of the number picker.
+ */
+ private int mScrollState = OnScrollListener.SCROLL_STATE_IDLE;
+
+ /**
* The callback interface used to indicate the number value has changed.
*/
- public interface OnChangedListener {
+ public interface OnChangeListener {
/**
+ * Called upon a change of the current value.
+ *
* @param picker The NumberPicker associated with this listener.
* @param oldVal The previous value.
* @param newVal The new value.
*/
- void onChanged(NumberPicker picker, int oldVal, int newVal);
+ void onChange(NumberPicker picker, int oldVal, int newVal);
}
/**
- * Interface used to format the number into a string for presentation
+ * Interface for listening to the picker scroll state.
+ */
+ public interface OnScrollListener {
+
+ /**
+ * The view is not scrolling.
+ */
+ public static int SCROLL_STATE_IDLE = 0;
+
+ /**
+ * The user is scrolling using touch, and their finger is still on the screen.
+ */
+ public static int SCROLL_STATE_TOUCH_SCROLL = 1;
+
+ /**
+ * The user had previously been scrolling using touch and performed a fling.
+ */
+ public static int SCROLL_STATE_FLING = 2;
+
+ /**
+ * Callback method to be invoked while the number picker is being scrolled.
+ *
+ * @param view The view whose scroll state is being reported
+ * @param scrollState The current scroll state. One of {@link #SCROLL_STATE_IDLE},
+ * {@link #SCROLL_STATE_TOUCH_SCROLL} or {@link #SCROLL_STATE_IDLE}.
+ */
+ public void onScrollStateChange(NumberPicker view, int scrollState);
+ }
+
+ /**
+ * Interface used to format the number into a string for presentation.
*/
public interface Formatter {
- String toString(int value);
+
+ /**
+ * Formats a string representation of the current index.
+ *
+ * @param value The currently selected value.
+ * @return A formatted string representation.
+ */
+ public String toString(int value);
}
/**
- * Create a new number picker
+ * Create a new number picker.
+ *
+ * @param context The application environment.
+ */
+ public NumberPicker(Context context) {
+ this(context, null);
+ }
+
+ /**
+ * Create a new number picker.
*
* @param context The application environment.
* @param attrs A collection of attributes.
@@ -492,11 +558,15 @@
mBeginEditOnUpEvent = false;
mAdjustScrollerOnUpEvent = true;
if (mDrawSelectorWheel) {
- mBeginEditOnUpEvent = mFlingScroller.isFinished()
+ boolean scrollersFinished = mFlingScroller.isFinished()
&& mAdjustScroller.isFinished();
+ if (!scrollersFinished) {
+ mFlingScroller.forceFinished(true);
+ mAdjustScroller.forceFinished(true);
+ tryNotifyScrollListener(OnScrollListener.SCROLL_STATE_IDLE);
+ }
+ mBeginEditOnUpEvent = scrollersFinished;
mAdjustScrollerOnUpEvent = true;
- mFlingScroller.forceFinished(true);
- mAdjustScroller.forceFinished(true);
hideInputControls();
return true;
}
@@ -512,6 +582,7 @@
int deltaDownY = (int) Math.abs(currentMoveY - mLastDownEventY);
if (deltaDownY > mTouchSlop) {
mBeginEditOnUpEvent = false;
+ tryNotifyScrollListener(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
setDrawSelectorWheel(true);
hideInputControls();
return true;
@@ -531,10 +602,12 @@
switch (action) {
case MotionEvent.ACTION_MOVE:
float currentMoveY = ev.getY();
- if (mBeginEditOnUpEvent) {
+ if (mBeginEditOnUpEvent
+ || mScrollState != OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
int deltaDownY = (int) Math.abs(currentMoveY - mLastDownEventY);
if (deltaDownY > mTouchSlop) {
mBeginEditOnUpEvent = false;
+ tryNotifyScrollListener(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
}
}
int deltaMoveY = (int) (currentMoveY - mLastMotionEventY);
@@ -550,6 +623,7 @@
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(
Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(mInputText, 0);
+ mInputText.setSelection(0, mInputText.getText().length());
return true;
}
VelocityTracker velocityTracker = mVelocityTracker;
@@ -557,6 +631,7 @@
int initialVelocity = (int) velocityTracker.getYVelocity();
if (Math.abs(initialVelocity) > mMinimumFlingVelocity) {
fling(initialVelocity);
+ tryNotifyScrollListener(OnScrollListener.SCROLL_STATE_FLING);
} else {
if (mAdjustScrollerOnUpEvent) {
if (mFlingScroller.isFinished() && mAdjustScroller.isFinished()) {
@@ -686,20 +761,40 @@
}
}
- /**
- * Set the callback that indicates the number has been adjusted by the user.
- *
- * @param listener the callback, should not be null.
- */
- public void setOnChangeListener(OnChangedListener listener) {
- mListener = listener;
+ @Override
+ public int getSolidColor() {
+ return mSolidColor;
}
/**
- * Set the formatter that will be used to format the number for presentation
+ * Sets the listener to be notified on change of the current value.
+ *
+ * @param onChangeListener The listener.
+ */
+ public void setOnChangeListener(OnChangeListener onChangeListener) {
+ mOnChangeListener = onChangeListener;
+ }
+
+ /**
+ * Set listener to be notified for scroll state changes.
+ *
+ * @param onScrollListener the callback, should not be null.
+ */
+ public void setOnScrollListener(OnScrollListener onScrollListener) {
+ mOnScrollListener = onScrollListener;
+ }
+
+ /**
+ * Set the formatter to be used for formatting the current value.
+ * <p>
+ * Note: If you have provided alternative values for the selected positons
+ * this formatter is never invoked.
+ * </p>
*
* @param formatter the formatter object. If formatter is null,
- * String.valueOf() will be used
+ * String.valueOf() will be used.
+ *
+ * @see #setRange(int, int, String[])
*/
public void setFormatter(Formatter formatter) {
mFormatter = formatter;
@@ -719,11 +814,11 @@
/**
* Set the range of numbers allowed for the number picker. The current value
* will be automatically set to the start. Also provide a mapping for values
- * used to display to the user.
+ * used to display to the user instead of the numbers in the range.
*
- * @param start the start of the range (inclusive)
- * @param end the end of the range (inclusive)
- * @param displayedValues the values displayed to the user.
+ * @param start The start of the range (inclusive).
+ * @param end The end of the range (inclusive).
+ * @param displayedValues The values displayed to the user.
*/
public void setRange(int start, int end, String[] displayedValues) {
boolean wrapSelector = (end - start) >= mSelectorIndices.length;
@@ -734,12 +829,20 @@
* Set the range of numbers allowed for the number picker. The current value
* will be automatically set to the start. Also provide a mapping for values
* used to display to the user.
+ * <p>
+ * Note: The <code>wrapSelectorWheel</code> argument is ignored if the range
+ * (difference between <code>start</code> and <code>end</code>) us less than
+ * five since this is the number of values shown by the selector wheel.
+ * </p>
*
* @param start the start of the range (inclusive)
* @param end the end of the range (inclusive)
* @param displayedValues the values displayed to the user.
+ * @param wrapSelectorWheel Whether to wrap the selector wheel.
+ *
+ * @see #setWrapSelectorWheel(boolean)
*/
- public void setRange(int start, int end, String[] displayedValues, boolean wrapSelector) {
+ public void setRange(int start, int end, String[] displayedValues, boolean wrapSelectorWheel) {
if (start < 0 || end < 0) {
throw new IllegalArgumentException("start and end must be > 0");
}
@@ -749,7 +852,7 @@
mEnd = end;
mCurrent = start;
- setWrapSelector(wrapSelector);
+ setWrapSelectorWheel(wrapSelectorWheel);
updateInputTextView();
if (displayedValues != null) {
@@ -768,8 +871,9 @@
* Set the current value for the number picker.
*
* @param current the current value the start of the range (inclusive)
+ *
* @throws IllegalArgumentException when current is not within the range of
- * of the number picker
+ * of the number picker.
*/
public void setCurrent(int current) {
if (current < mStart || current > mEnd) {
@@ -781,12 +885,14 @@
}
/**
- * Sets whether the selector shown during flinging/scrolling should wrap
- * around the beginning and end values.
+ * Sets whether the selector wheel shown during flinging/scrolling should wrap
+ * around the beginning and end values. By default if the range is more than
+ * five (the number of items shown on the selector wheel) the selector wheel
+ * wrapping is enabled.
*
* @param wrapSelector Whether to wrap.
*/
- public void setWrapSelector(boolean wrapSelector) {
+ public void setWrapSelectorWheel(boolean wrapSelector) {
if (wrapSelector && (mEnd - mStart) < mSelectorIndices.length) {
throw new IllegalStateException("Range less than selector items count.");
}
@@ -798,18 +904,18 @@
}
/**
- * Sets the speed at which the numbers will scroll when the +/- buttons are
- * longpressed
+ * Sets the speed at which the numbers be incremented and decremented when
+ * the up and down buttons are long pressed respectively.
*
- * @param speed The speed (in milliseconds) at which the numbers will scroll
- * default 300ms
+ * @param intervalMillis The speed (in milliseconds) at which the numbers
+ * will be incremented and decremented (default 300ms).
*/
- public void setSpeed(long speed) {
- mLongPressUpdateSpeed = speed;
+ public void setOnLongPressUpdateInterval(long intervalMillis) {
+ mLongPressUpdateInterval = intervalMillis;
}
/**
- * Returns the current value of the NumberPicker
+ * Returns the current value of the NumberPicker.
*
* @return the current value.
*/
@@ -817,9 +923,22 @@
return mCurrent;
}
- @Override
- public int getSolidColor() {
- return mSolidColor;
+ /**
+ * Returns the range lower value of the NumberPicker.
+ *
+ * @return The lower number of the range.
+ */
+ public int getRangeStart() {
+ return mStart;
+ }
+
+ /**
+ * Returns the range end value of the NumberPicker.
+ *
+ * @return The upper number of the range.
+ */
+ public int getRangeEnd() {
+ return mEnd;
}
@Override
@@ -892,24 +1011,6 @@
}
/**
- * Returns the upper value of the range of the NumberPicker
- *
- * @return the uppper number of the range.
- */
- protected int getEndRange() {
- return mEnd;
- }
-
- /**
- * Returns the lower value of the range of the NumberPicker
- *
- * @return the lower number of the range.
- */
- protected int getBeginRange() {
- return mStart;
- }
-
- /**
* Sets the current value of this NumberPicker, and sets mPrevious to the
* previous value. If current is greater than mEnd less than mStart, the
* value of mCurrent is wrapped around. Subclasses can override this to
@@ -966,6 +1067,7 @@
private void onScrollerFinished(Scroller scroller) {
if (scroller == mFlingScroller) {
postAdjustScrollerCommand(0);
+ tryNotifyScrollListener(OnScrollListener.SCROLL_STATE_IDLE);
} else {
showInputControls();
updateInputTextView();
@@ -973,6 +1075,17 @@
}
/**
+ * Notifies the scroll listener for the given <code>scrollState</code>
+ * if the scroll state differs from the current scroll state.
+ */
+ private void tryNotifyScrollListener(int scrollState) {
+ if (mOnScrollListener != null && mScrollState != scrollState) {
+ mScrollState = scrollState;
+ mOnScrollListener.onScrollStateChange(this, scrollState);
+ }
+ }
+
+ /**
* Flings the selector with the given <code>velocityY</code>.
*/
private void fling(int velocityY) {
@@ -1118,7 +1231,8 @@
scrollSelectorValue = "";
} else {
if (mDisplayedValues != null) {
- scrollSelectorValue = mDisplayedValues[selectorIndex];
+ int displayedValueIndex = selectorIndex - mStart;
+ scrollSelectorValue = mDisplayedValues[displayedValueIndex];
} else {
scrollSelectorValue = formatNumber(selectorIndex);
}
@@ -1167,8 +1281,8 @@
* NumberPicker.
*/
private void notifyChange(int previous, int current) {
- if (mListener != null) {
- mListener.onChanged(this, previous, mCurrent);
+ if (mOnChangeListener != null) {
+ mOnChangeListener.onChange(this, previous, mCurrent);
}
}
@@ -1368,7 +1482,7 @@
public void run() {
changeCurrent(mCurrent + mUpdateStep);
- postDelayed(this, mLongPressUpdateSpeed);
+ postDelayed(this, mLongPressUpdateInterval);
}
}
}
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 9fa90dc..f25edd8 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -1467,8 +1467,8 @@
final int restoreCount = canvas.save();
final int width = getWidth();
- canvas.translate(-width / 2, Math.min(0, scrollY));
- mEdgeGlowTop.setSize(width * 2, getHeight());
+ canvas.translate(0, Math.min(0, scrollY));
+ mEdgeGlowTop.setSize(width, getHeight());
if (mEdgeGlowTop.draw(canvas)) {
invalidate();
}
@@ -1479,9 +1479,9 @@
final int width = getWidth();
final int height = getHeight();
- canvas.translate(-width / 2, Math.max(getScrollRange(), scrollY) + height);
+ canvas.translate(-width, Math.max(getScrollRange(), scrollY) + height);
canvas.rotate(180, width, 0);
- mEdgeGlowBottom.setSize(width * 2, height);
+ mEdgeGlowBottom.setSize(width, height);
if (mEdgeGlowBottom.draw(canvas)) {
invalidate();
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index a86610dd..144cf9c 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -3933,6 +3933,9 @@
hideError();
}
+ if (mBlink != null) {
+ mBlink.cancel();
+ }
hideControllers();
}
@@ -6282,11 +6285,7 @@
mCursorVisible = visible;
invalidate();
- if (visible) {
- makeBlink();
- } else if (mBlink != null) {
- mBlink.removeCallbacks(mBlink);
- }
+ makeBlink();
// InsertionPointCursorController depends on mCursorVisible
prepareCursorControllers();
@@ -6782,7 +6781,7 @@
}
private void makeBlink() {
- if (!mCursorVisible) {
+ if (!mCursorVisible || !isTextEditable()) {
if (mBlink != null) {
mBlink.removeCallbacks(mBlink);
}
@@ -7134,6 +7133,7 @@
mLayout != null;
if (!mInsertionControllerEnabled) {
+ hideInsertionPointCursorController();
mInsertionPointCursorController = null;
}
@@ -7388,14 +7388,14 @@
}
private boolean canSelectText() {
- return textCanBeSelected() && mText.length() != 0;
+ return hasSelectionController() && mText.length() != 0;
}
private boolean textCanBeSelected() {
// prepareCursorController() relies on this method.
// If you change this condition, make sure prepareCursorController is called anywhere
// the value of this condition might be changed.
- return (mText instanceof Spannable && mMovement != null && mMovement.canSelectArbitrarily());
+ return mText instanceof Spannable && mMovement != null && mMovement.canSelectArbitrarily();
}
private boolean canCut() {
@@ -7529,6 +7529,10 @@
}
private void selectCurrentWord() {
+ if (!canSelectText()) {
+ return;
+ }
+
if (hasPasswordTransformationMethod()) {
// selectCurrentWord is not available on a password field and would return an
// arbitrary 10-charater selection around pressed position. Select all instead.
@@ -7544,7 +7548,6 @@
minOffset = getSelectionStart();
maxOffset = getSelectionEnd();
} else {
- // selectionModifierCursorController is guaranteed to exist at that point
SelectionModifierCursorController selectionController = getSelectionController();
minOffset = selectionController.getMinTouchOffset();
maxOffset = selectionController.getMaxTouchOffset();
@@ -7921,12 +7924,8 @@
selectCurrentWord();
ActionMode.Callback actionModeCallback = new SelectionActionModeCallback();
- if (actionModeCallback != null) {
- mSelectionActionMode = startActionMode(actionModeCallback);
- return mSelectionActionMode != null;
- }
-
- return false;
+ mSelectionActionMode = startActionMode(actionModeCallback);
+ return mSelectionActionMode != null;
}
/**
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index 6cf1387..203b637 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -25,7 +25,7 @@
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
-import android.widget.NumberPicker.OnChangedListener;
+import android.widget.NumberPicker.OnChangeListener;
import java.text.DateFormatSymbols;
import java.util.Calendar;
@@ -110,8 +110,8 @@
// hour
mHourPicker = (NumberPicker) findViewById(R.id.hour);
- mHourPicker.setOnChangeListener(new NumberPicker.OnChangedListener() {
- public void onChanged(NumberPicker spinner, int oldVal, int newVal) {
+ mHourPicker.setOnChangeListener(new NumberPicker.OnChangeListener() {
+ public void onChange(NumberPicker spinner, int oldVal, int newVal) {
mCurrentHour = newVal;
if (!mIs24HourView) {
// adjust from [1-12] to [0-11] internally, with the times
@@ -135,10 +135,10 @@
// digits of minute
mMinutePicker = (NumberPicker) findViewById(R.id.minute);
mMinutePicker.setRange(0, 59);
- mMinutePicker.setSpeed(100);
+ mMinutePicker.setOnLongPressUpdateInterval(100);
mMinutePicker.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER);
- mMinutePicker.setOnChangeListener(new NumberPicker.OnChangedListener() {
- public void onChanged(NumberPicker spinner, int oldVal, int newVal) {
+ mMinutePicker.setOnChangeListener(new NumberPicker.OnChangeListener() {
+ public void onChange(NumberPicker spinner, int oldVal, int newVal) {
mCurrentMinute = newVal;
onTimeChanged();
}
@@ -146,8 +146,8 @@
// am/pm
mAmPmPicker = (NumberPicker) findViewById(R.id.amPm);
- mAmPmPicker.setOnChangeListener(new OnChangedListener() {
- public void onChanged(NumberPicker picker, int oldVal, int newVal) {
+ mAmPmPicker.setOnChangeListener(new OnChangeListener() {
+ public void onChange(NumberPicker picker, int oldVal, int newVal) {
picker.requestFocus();
if (mIsAm) {
// Currently AM switching to PM
@@ -184,7 +184,7 @@
setEnabled(false);
}
}
-
+
@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
diff --git a/core/java/com/android/internal/app/NetInitiatedActivity.java b/core/java/com/android/internal/app/NetInitiatedActivity.java
index 36f45b2..6039cc2 100755
--- a/core/java/com/android/internal/app/NetInitiatedActivity.java
+++ b/core/java/com/android/internal/app/NetInitiatedActivity.java
@@ -26,6 +26,8 @@
import android.widget.Toast;
import android.util.Log;
import android.location.LocationManager;
+
+import com.android.internal.R;
import com.android.internal.location.GpsNetInitiatedHandler;
/**
@@ -42,10 +44,6 @@
private static final int POSITIVE_BUTTON = AlertDialog.BUTTON_POSITIVE;
private static final int NEGATIVE_BUTTON = AlertDialog.BUTTON_NEGATIVE;
- // Dialog button text
- public static final String BUTTON_TEXT_ACCEPT = "Accept";
- public static final String BUTTON_TEXT_DENY = "Deny";
-
// Received ID from intent, -1 when no notification is in progress
private int notificationId = -1;
@@ -67,12 +65,13 @@
// Set up the "dialog"
final Intent intent = getIntent();
final AlertController.AlertParams p = mAlertParams;
+ Context context = getApplicationContext();
p.mIconId = com.android.internal.R.drawable.ic_dialog_usb;
p.mTitle = intent.getStringExtra(GpsNetInitiatedHandler.NI_INTENT_KEY_TITLE);
p.mMessage = intent.getStringExtra(GpsNetInitiatedHandler.NI_INTENT_KEY_MESSAGE);
- p.mPositiveButtonText = BUTTON_TEXT_ACCEPT;
+ p.mPositiveButtonText = String.format(context.getString(R.string.gpsVerifYes));
p.mPositiveButtonListener = this;
- p.mNegativeButtonText = BUTTON_TEXT_DENY;
+ p.mNegativeButtonText = String.format(context.getString(R.string.gpsVerifNo));
p.mNegativeButtonListener = this;
notificationId = intent.getIntExtra(GpsNetInitiatedHandler.NI_INTENT_KEY_NOTIF_ID, -1);
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 848bf9e..dea53bf 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -557,8 +557,6 @@
public static void main(String argv[]) {
try {
- VMRuntime.getRuntime().setMinimumHeapSize(5 * 1024 * 1024);
-
// Start profiling the zygote initialization.
SamplingProfilerIntegration.start();
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index bcd7bae..8eeed3d 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -51,11 +51,11 @@
android_view_InputChannel.cpp \
android_view_InputQueue.cpp \
android_view_KeyEvent.cpp \
+ android_view_KeyCharacterMap.cpp \
android_view_GLES20Canvas.cpp \
android_view_MotionEvent.cpp \
android_text_AndroidCharacter.cpp \
android_text_AndroidBidi.cpp \
- android_text_KeyCharacterMap.cpp \
android_os_Debug.cpp \
android_os_FileUtils.cpp \
android_os_MemoryFile.cpp \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index e50233e..a21f0ab 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -576,6 +576,7 @@
char dexoptFlagsBuf[PROPERTY_VALUE_MAX];
char enableAssertBuf[sizeof("-ea:")-1 + PROPERTY_VALUE_MAX];
char jniOptsBuf[sizeof("-Xjniopts:")-1 + PROPERTY_VALUE_MAX];
+ char heapstartsizeOptsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX];
char heapsizeOptsBuf[sizeof("-Xmx")-1 + PROPERTY_VALUE_MAX];
char extraOptsBuf[PROPERTY_VALUE_MAX];
char* stackTraceFile = NULL;
@@ -650,6 +651,11 @@
mOptions.add(opt);
//options[curOpt++].optionString = "-verbose:class";
+ strcpy(heapstartsizeOptsBuf, "-Xms");
+ property_get("dalvik.vm.heapstartsize", heapstartsizeOptsBuf+4, "2m");
+ opt.optionString = heapstartsizeOptsBuf;
+ mOptions.add(opt);
+
strcpy(heapsizeOptsBuf, "-Xmx");
property_get("dalvik.vm.heapsize", heapsizeOptsBuf+4, "16m");
//LOGI("Heap size: %s", heapsizeOptsBuf);
diff --git a/core/jni/android_text_KeyCharacterMap.cpp b/core/jni/android_view_KeyCharacterMap.cpp
similarity index 78%
rename from core/jni/android_text_KeyCharacterMap.cpp
rename to core/jni/android_view_KeyCharacterMap.cpp
index a7e62c1..bfeec4f 100644
--- a/core/jni/android_text_KeyCharacterMap.cpp
+++ b/core/jni/android_view_KeyCharacterMap.cpp
@@ -29,6 +29,14 @@
jclass clazz;
} gKeyEventClassInfo;
+static struct {
+ jclass clazz;
+
+ jfieldID keyCode;
+ jfieldID metaState;
+} gFallbackActionClassInfo;
+
+
static jint nativeLoad(JNIEnv *env, jobject clazz, jint deviceId) {
KeyCharacterMap* map;
status_t status = KeyCharacterMap::loadByDeviceId(deviceId, &map);
@@ -54,6 +62,21 @@
return map->getCharacter(keyCode, metaState);
}
+static jboolean nativeGetFallbackAction(JNIEnv *env, jobject clazz, jint ptr, jint keyCode,
+ jint metaState, jobject fallbackActionObj) {
+ KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
+ KeyCharacterMap::FallbackAction fallbackAction;
+
+ bool result = map->getFallbackAction(keyCode, metaState, &fallbackAction);
+ if (result) {
+ env->SetIntField(fallbackActionObj, gFallbackActionClassInfo.keyCode,
+ fallbackAction.keyCode);
+ env->SetIntField(fallbackActionObj, gFallbackActionClassInfo.metaState,
+ fallbackAction.metaState);
+ }
+ return result;
+}
+
static jchar nativeGetNumber(JNIEnv *env, jobject clazz, jint ptr, jint keyCode) {
KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
return map->getNumber(keyCode);
@@ -126,6 +149,8 @@
(void*)nativeDispose },
{ "nativeGetCharacter", "(III)C",
(void*)nativeGetCharacter },
+ { "nativeGetFallbackAction", "(IIILandroid/view/KeyCharacterMap$FallbackAction;)Z",
+ (void*)nativeGetFallbackAction },
{ "nativeGetNumber", "(II)C",
(void*)nativeGetNumber },
{ "nativeGetMatch", "(II[CI)C",
@@ -143,10 +168,22 @@
LOG_FATAL_IF(! var, "Unable to find class " className); \
var = jclass(env->NewGlobalRef(var));
+#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
+ var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
+ LOG_FATAL_IF(! var, "Unable to find field " fieldName);
+
int register_android_text_KeyCharacterMap(JNIEnv* env)
{
FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
+ FIND_CLASS(gFallbackActionClassInfo.clazz, "android/view/KeyCharacterMap$FallbackAction");
+
+ GET_FIELD_ID(gFallbackActionClassInfo.keyCode, gFallbackActionClassInfo.clazz,
+ "keyCode", "I");
+
+ GET_FIELD_ID(gFallbackActionClassInfo.metaState, gFallbackActionClassInfo.clazz,
+ "metaState", "I");
+
return AndroidRuntime::registerNativeMethods(env,
"android/view/KeyCharacterMap", g_methods, NELEM(g_methods));
}
diff --git a/core/res/res/drawable-hdpi/simple_week_dayline_holo_light.9.png b/core/res/res/drawable-hdpi/simple_week_dayline_holo_light.9.png
new file mode 100644
index 0000000..ed1a5e9
--- /dev/null
+++ b/core/res/res/drawable-hdpi/simple_week_dayline_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/simple_week_dayline_holo_light.9.png b/core/res/res/drawable-mdpi/simple_week_dayline_holo_light.9.png
new file mode 100644
index 0000000..f264cb6
--- /dev/null
+++ b/core/res/res/drawable-mdpi/simple_week_dayline_holo_light.9.png
Binary files differ
diff --git a/core/res/res/layout/date_picker.xml b/core/res/res/layout/date_picker.xml
index 4fd46b3..5c023ee 100644
--- a/core/res/res/layout/date_picker.xml
+++ b/core/res/res/layout/date_picker.xml
@@ -19,45 +19,74 @@
<!-- Layout of date picker-->
-<!-- Warning: everything within the parent is removed and re-ordered depending
- on the date format selected by the user. -->
+<!-- Warning: everything within the "pickers" layout is removed and re-ordered
+ depending on the date format selected by the user.
+-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/parent"
- android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
android:layout_gravity="center_horizontal"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
+ android:orientation="horizontal"
+ android:gravity="center">
- <!-- Month -->
- <NumberPicker
- android:id="@+id/month"
- android:layout_width="80dip"
+ <LinearLayout android:id="@+id/pickers"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginLeft="1dip"
- android:layout_marginRight="1dip"
- android:focusable="true"
- android:focusableInTouchMode="true"
- />
+ android:layout_marginRight="15dip"
+ android:layout_weight="0.5"
+ android:orientation="horizontal"
+ android:gravity="center">
- <!-- Day -->
- <NumberPicker
- android:id="@+id/day"
- android:layout_width="80dip"
- android:layout_height="wrap_content"
- android:layout_marginLeft="1dip"
- android:layout_marginRight="1dip"
- android:focusable="true"
- android:focusableInTouchMode="true"
- />
+ <!-- Month -->
+ <NumberPicker
+ android:id="@+id/month"
+ android:layout_width="48dip"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="15dip"
+ android:layout_marginRight="15dip"
+ android:layout_marginTop="35dip"
+ android:layout_marginBottom="35dip"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ />
- <!-- Year -->
- <NumberPicker
- android:id="@+id/year"
- android:layout_width="95dip"
- android:layout_height="wrap_content"
- android:layout_marginLeft="1dip"
- android:layout_marginRight="1dip"
- android:focusable="true"
- android:focusableInTouchMode="true"
- />
+ <!-- Day -->
+ <NumberPicker
+ android:id="@+id/day"
+ android:layout_width="48dip"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="15dip"
+ android:layout_marginRight="15dip"
+ android:layout_marginTop="35dip"
+ android:layout_marginBottom="35dip"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ />
+
+ <!-- Year -->
+ <NumberPicker
+ android:id="@+id/year"
+ android:layout_width="48dip"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="15dip"
+ android:layout_marginRight="15dip"
+ android:layout_marginTop="35dip"
+ android:layout_marginBottom="35dip"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ />
+
+ </LinearLayout>
+
+ <!-- mini-month day-picker -->
+ <DayPicker
+ android:id="@+id/mini_month_day_picker"
+ android:layout_width="200dip"
+ android:layout_height="230dip"
+ android:layout_marginLeft="15dip"
+ android:layout_weight="0.5"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ />
+
</LinearLayout>
diff --git a/core/res/res/layout/date_picker_dialog.xml b/core/res/res/layout/date_picker_dialog.xml
index 949c8a3..90de1f5 100644
--- a/core/res/res/layout/date_picker_dialog.xml
+++ b/core/res/res/layout/date_picker_dialog.xml
@@ -17,9 +17,14 @@
*/
-->
+<!-- Note: We want the DatePicker to take as much space as possible, therefore
+ we set the width and height bigger than the max AlertDialog size
+ determined by our parent WeightedLinearLayout.
+
+ See: alert_dialog.xml
+-->
<DatePicker xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/datePicker"
- android:padding="5dip"
android:layout_gravity="center_horizontal"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
+ android:layout_width="250dip"
+ android:layout_height="600dip"/>
diff --git a/core/res/res/layout/day_picker.xml b/core/res/res/layout/day_picker.xml
new file mode 100644
index 0000000..46ab450
--- /dev/null
+++ b/core/res/res/layout/day_picker.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* Copyright 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.
+*/
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:fillViewport="true" >
+
+ <TextView android:id="@+android:id/month_name"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:paddingTop="10dip"
+ android:paddingBottom="10dip"
+ style="@android:style/TextAppearance.Medium" />
+
+ <LinearLayout android:id="@+android:id/day_names"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="6dip"
+ android:layout_marginRight="2dip"
+ android:layout_marginLeft="2dip"
+ android:gravity="center">
+
+ <TextView android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:gravity="center"
+ android:visibility="gone" />
+
+ <TextView android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:gravity="center"
+ style="?android:attr/dayPickerWeekDayViewStyle" />
+
+ <TextView android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:gravity="center"
+ style="?android:attr/dayPickerWeekDayViewStyle" />
+
+ <TextView android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:gravity="center"
+ style="?android:attr/dayPickerWeekDayViewStyle" />
+
+ <TextView android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:gravity="center"
+ style="?android:attr/dayPickerWeekDayViewStyle" />
+
+ <TextView android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:gravity="center"
+ style="?android:attr/dayPickerWeekDayViewStyle" />
+
+ <TextView android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:gravity="center"
+ style="?android:attr/dayPickerWeekDayViewStyle" />
+
+ <TextView android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:gravity="center"
+ style="?android:attr/dayPickerWeekDayViewStyle" />
+
+ </LinearLayout>
+
+ <ListView android:id="@android:id/list"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:drawSelectorOnTop="false"
+ android:cacheColorHint="@android:color/transparent"
+ android:fastScrollEnabled="false"
+ android:overScrollMode="never" />
+
+</LinearLayout>
diff --git a/core/res/res/layout/time_picker.xml b/core/res/res/layout/time_picker.xml
index fa288422..bf81c18 100644
--- a/core/res/res/layout/time_picker.xml
+++ b/core/res/res/layout/time_picker.xml
@@ -30,7 +30,7 @@
android:id="@+id/hour"
android:layout_width="48dip"
android:layout_height="wrap_content"
- android:layout_marginRight="20dip"
+ android:layout_marginRight="13dip"
android:layout_marginTop="35dip"
android:layout_marginBottom="35dip"
android:focusable="true"
@@ -50,8 +50,8 @@
android:id="@+id/minute"
android:layout_width="48dip"
android:layout_height="wrap_content"
- android:layout_marginLeft="20dip"
- android:layout_marginRight="22dip"
+ android:layout_marginLeft="13dip"
+ android:layout_marginRight="15dip"
android:layout_marginTop="35dip"
android:layout_marginBottom="35dip"
android:focusable="true"
@@ -63,7 +63,7 @@
android:id="@+id/amPm"
android:layout_width="48dip"
android:layout_height="wrap_content"
- android:layout_marginLeft="22dip"
+ android:layout_marginLeft="15dip"
android:layout_marginTop="35dip"
android:layout_marginBottom="35dip"
android:focusable="true"
diff --git a/core/res/res/layout/time_picker_dialog.xml b/core/res/res/layout/time_picker_dialog.xml
index d5a6b5e..09326c8 100644
--- a/core/res/res/layout/time_picker_dialog.xml
+++ b/core/res/res/layout/time_picker_dialog.xml
@@ -22,4 +22,4 @@
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:padding="5dip" />
+ />
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 109fb0d..4bd91b3 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -503,16 +503,23 @@
<attr name="listPopupWindowStyle" format="reference" />
<!-- Default PopupMenu style. -->
<attr name="popupMenuStyle" format="reference" />
- <!-- NumberPicker up button style -->
+
+ <!-- @hide NumberPicker up button style -->
<attr name="numberPickerUpButtonStyle" format="reference" />
- <!-- NumberPicker down button style -->
+ <!-- @hide NumberPicker down button style -->
<attr name="numberPickerDownButtonStyle" format="reference" />
- <!-- NumberPicker input text style -->
+ <!-- @hide NumberPicker input text style -->
<attr name="numberPickerInputTextStyle" format="reference" />
- <!-- NumberPicker the fading edge length of the selector wheel -->
+ <!-- @hide NumberPicker the fading edge length of the selector wheel -->
<attr name="numberPickerStyle" format="reference" />
+ <!-- @hide DayPicker$WeekView style-->
+ <attr name="dayPickerWeekViewStyle" format="reference" />
+
+ <!-- @hide DayPickerDayView style-->
+ <attr name="dayPickerWeekDayViewStyle" format="reference" />
+
<!-- =================== -->
<!-- Action bar styles -->
<!-- =================== -->
@@ -1260,6 +1267,7 @@
<enum name="KEYCODE_PROG_GREEN" value="184" />
<enum name="KEYCODE_PROG_YELLOW" value="185" />
<enum name="KEYCODE_PROG_BLUE" value="186" />
+ <enum name="KEYCODE_APP_SWITCH" value="187" />
</attr>
<!-- ***************************************************************** -->
@@ -2943,6 +2951,16 @@
</declare-styleable>
<!-- @hide -->
+ <declare-styleable name="DayPickerWeekView">
+ <attr name="selectionBackgroundColor" format="color|reference" />
+ <attr name="focusedMonthDateColor" format="color|reference" />
+ <attr name="otherMonthDateColor" format="color|reference" />
+ <attr name="weekNumberColor" format="color|reference" />
+ <attr name="gridLinesColor" format="color|reference" />
+ <attr name="selectedDayLine" format="reference" />
+ </declare-styleable>
+
+ <!-- @hide -->
<declare-styleable name="NumberPicker">
<attr name="orientation" />
<attr name="solidColor" format="color|reference" />
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index ae029e5..8fa1d32 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1567,6 +1567,6 @@
<public type="style" name="Holo.Light.ButtonBar.AlertDialog" />
<public type="style" name="Holo.SegmentedButton" />
<public type="style" name="Holo.Light.SegmentedButton" />
-
<public type="string" name="selectTextMode" />
+
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 0f5ff05..2e235f0 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2295,6 +2295,8 @@
<!-- The title of the time picker dialog. [CHAR LIMIT=NONE] -->
<string name="time_picker_dialog_title">Set time</string>
+ <!-- The title of the date picker dialog. [CHAR LIMIT=NONE] -->
+ <string name="date_picker_dialog_title">Set date</string>
<!-- Name of the button in the date/time picker to accept the date/time change -->
<string name="date_time_set">Set</string>
@@ -2621,4 +2623,19 @@
<!-- ActionBar action to use the current selection to open the Find on page functionality [CHAR LIMIT=10]-->
<string name="find">Find</string>
+ <!-- Network positioning notification ticker. The name of the user (e.g. John Doe) who sent
+ the request is shown as a dynamic string. -->
+ <string name="gpsNotifTicker">Location request from <xliff:g id="name">%s</xliff:g></string>
+ <!-- Network positioning notification and verification title to inform the user about
+ an incoming location request. -->
+ <string name="gpsNotifTitle">Location request</string>
+ <!-- Network positioning notification message. The name of the user (e.g. John Doe) and
+ service (SUPL-service) who sent the request is shown as dynamic strings.
+ Translation should not be longer than master text. -->
+ <string name="gpsNotifMessage">Requested by <xliff:g id="name">%1$s</xliff:g> (<xliff:g id="service" example="SUPL-service">%2$s</xliff:g>)</string>
+ <!-- Network positioning verification Yes. Button to push to share location information. -->
+ <string name="gpsVerifYes">Yes</string>
+ <!-- Network positioning verification No. Button to push to deny sharing of location
+ information. -->
+ <string name="gpsVerifNo">No</string>
</resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 58553e1..8d7556f 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -238,6 +238,11 @@
<item name="android:textColor">#ff272727</item>
</style>
+ <!-- @hide -->
+ <style name="TextAppearance.Small.DayPickerWeekDayView">
+ <item name="android:textStyle">bold</item>
+ </style>
+
<!-- Widget Styles -->
<style name="Widget">
@@ -468,21 +473,35 @@
<item name="android:background">@android:drawable/btn_default</item>
</style>
+ <!-- @hide -->
+ <style name="Widget.DayPickerWeekView">
+ <item name="android:selectionBackgroundColor">#330099FF</item>
+ <item name="android:focusedMonthDateColor">#FFFFFFFF</item>
+ <item name="android:otherMonthDateColor">#66FFFFFF</item>
+ <item name="android:weekNumberColor">#33FFFFFF</item>
+ <item name="android:gridLinesColor">#19FFFFFF</item>
+ <item name="selectedDayLine">@android:drawable/simple_week_dayline_holo_light</item>
+ </style>
+
+ <!-- @hide -->
<style name="Widget.NumberPicker">
<item name="android:orientation">vertical</item>
<item name="android:fadingEdge">vertical</item>
<item name="android:fadingEdgeLength">50dip</item>
- <item name="android:solidColor">?android:attr/colorBackground</item>
+ <item name="android:solidColor">@android:color/transparent</item>
</style>
+ <!-- @hide -->
<style name="Widget.ImageButton.NumberPickerUpButton">
<item name="android:background">@android:drawable/timepicker_up_btn</item>
</style>
+ <!-- @hide -->
<style name="Widget.ImageButton.NumberPickerDownButton">
<item name="android:background">@android:drawable/timepicker_down_btn</item>
</style>
+ <!-- @hide -->
<style name="Widget.EditText.NumberPickerInputText">
<item name="android:textAppearance">@style/TextAppearance.Large.Inverse.NumberPickerInputText</item>
<item name="android:gravity">center</item>
@@ -834,6 +853,7 @@
<item name="android:textStyle">bold</item>
</style>
+ <!-- @hide -->
<style name="TextAppearance.Large.Inverse.NumberPickerInputText">
<item name="android:textColor">@android:color/primary_text_light</item>
<item name="android:textSize">30sp</item>
@@ -1200,6 +1220,11 @@
<item name="android:textSize">18sp</item>
</style>
+ <!-- @hide -->
+ <style name="TextAppearance.Holo.DayPickerWeekDayView" parent="TextAppearance.Small.DayPickerWeekDayView">
+ <item name="android:textColor">#505050</item>
+ </style>
+
<!-- Light text styles -->
<style name="TextAppearance.Holo.Light" parent="TextAppearance.Holo">
</style>
@@ -1296,6 +1321,10 @@
<item name="android:textSize">18sp</item>
</style>
+ <!-- @hide -->
+ <style name="TextAppearance.Holo.Light.DayPickerWeekDayView" parent="TextAppearance.Small.DayPickerWeekDayView">
+ </style>
+
<!-- Widget Styles -->
<style name="Widget.Holo" parent="Widget">
@@ -1406,22 +1435,35 @@
<item name="android:listSelector">?android:attr/selectableItemBackground</item>
</style>
+ <!-- @hide -->
+ <style name="Widget.Holo.DayPickerWeekView">
+ <item name="android:selectionBackgroundColor">#330099FF</item>
+ <item name="android:focusedMonthDateColor">#FFFFFFFF</item>
+ <item name="android:otherMonthDateColor">#66FFFFFF</item>
+ <item name="android:weekNumberColor">#33FFFFFF</item>
+ <item name="android:gridLinesColor">#19FFFFFF</item>
+ <item name="selectedDayLine">@android:drawable/simple_week_dayline_holo_light</item>
+ </style>
+
<style name="Widget.Holo.ImageButton" parent="Widget.ImageButton">
<item name="android:background">@android:drawable/btn_default_holo_dark</item>
</style>
+ <!-- @hide -->
<style name="Widget.Holo.ImageButton.NumberPickerUpButton">
<item name="android:background">@null</item>
<item name="android:paddingBottom">26sp</item>
<item name="android:src">@android:drawable/timepicker_up_btn_holo_dark</item>
</style>
+ <!-- @hide -->
<style name="Widget.Holo.ImageButton.NumberPickerDownButton">
<item name="android:background">@null</item>
<item name="android:paddingTop">26sp</item>
<item name="android:src">@android:drawable/timepicker_down_btn_holo_dark</item>
</style>
+ <!-- @hide -->
<style name="Widget.Holo.EditText.NumberPickerInputText">
<item name="android:paddingTop">13sp</item>
<item name="android:paddingBottom">13sp</item>
@@ -1767,14 +1809,21 @@
<item name="android:background">@android:drawable/btn_default_holo_light</item>
</style>
+ <!-- @hide -->
+ <style name="Widget.Holo.Light.DayPickerWeekView" parent="Widget.DayPickerWeekView">
+ </style>
+
+ <!-- @hide -->
<style name="Widget.Holo.Light.ImageButton.NumberPickerUpButton" parent="Widget.Holo.Light.ImageButton.NumberPickerUpButton">
<item name="android:background">@android:drawable/timepicker_up_btn_holo_light</item>
</style>
+ <!-- @hide -->
<style name="Widget.Holo.Light.ImageButton.NumberPickerDownButton" parent="Widget.Holo.ImageButton.NumberPickerDownButton">
<item name="android:background">@android:drawable/timepicker_down_btn_holo_light</item>
</style>
+ <!-- @hide -->
<style name="Widget.Holo.Light.EditText.NumberPickerInputText" parent="Widget.Holo.EditText.NumberPickerInputText">
</style>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 0f21e9f..94e8f96 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -26,7 +26,7 @@
of it a dark color.
-->
<style name="Theme">
-
+
<item name="colorForeground">@android:color/bright_foreground_dark</item>
<item name="colorForegroundInverse">@android:color/bright_foreground_dark_inverse</item>
<item name="colorBackground">@android:color/background_dark</item>
@@ -280,6 +280,12 @@
<item name="numberPickerInputTextStyle">@style/Widget.EditText.NumberPickerInputText</item>
<item name="numberPickerStyle">@style/Widget.NumberPicker</item>
+ <!-- DayPicker$WeekView style-->
+ <item name="dayPickerWeekViewStyle">@style/Widget.DayPickerWeekView</item>
+
+ <!-- DayPickerWeekDayView style-->
+ <item name="dayPickerWeekDayViewStyle">@style/TextAppearance.Small.DayPickerWeekDayView</item>
+
</style>
<!-- Variant of the default (dark) theme with no title bar -->
@@ -917,6 +923,12 @@
<item name="numberPickerDownButtonStyle">@style/Widget.Holo.ImageButton.NumberPickerDownButton</item>
<item name="numberPickerInputTextStyle">@style/Widget.Holo.EditText.NumberPickerInputText</item>
+ <!-- DayPicker$WeekView style-->
+ <item name="dayPickerWeekViewStyle">@style/Widget.Holo.DayPickerWeekView</item>
+
+ <!-- DayPickerWeekDayView style-->
+ <item name="dayPickerWeekDayViewStyle">@style/TextAppearance.Holo.DayPickerWeekDayView</item>
+
</style>
<!-- New Honeycomb holographic theme. Light version. The widgets in the
@@ -1162,6 +1174,12 @@
<item name="numberPickerDownButtonStyle">@style/Widget.Holo.Light.ImageButton.NumberPickerDownButton</item>
<item name="numberPickerInputTextStyle">@style/Widget.Holo.Light.EditText.NumberPickerInputText</item>
+ <!-- DayPicker$WeekView style-->
+ <item name="dayPickerWeekViewStyle">@style/Widget.Holo.Light.DayPickerWeekView</item>
+
+ <!-- DayPickerWeekDayView style-->
+ <item name="dayPickerWeekDayViewStyle">@style/TextAppearance.Holo.Light.DayPickerWeekDayView</item>
+
</style>
<!-- Development legacy name; if you're using this, switch. -->
diff --git a/core/tests/ConnectivityManagerTest/Android.mk b/core/tests/ConnectivityManagerTest/Android.mk
index a1546fa..56011f7 100644
--- a/core/tests/ConnectivityManagerTest/Android.mk
+++ b/core/tests/ConnectivityManagerTest/Android.mk
@@ -25,6 +25,6 @@
LOCAL_PACKAGE_NAME := ConnectivityManagerTest
-#LOCAL_INSTRUMENTATION_FOR := connectivitymanagertest
+LOCAL_CERTIFICATE := platform
include $(BUILD_PACKAGE)
diff --git a/core/tests/ConnectivityManagerTest/AndroidManifest.xml b/core/tests/ConnectivityManagerTest/AndroidManifest.xml
index b116bea..05f8b39 100644
--- a/core/tests/ConnectivityManagerTest/AndroidManifest.xml
+++ b/core/tests/ConnectivityManagerTest/AndroidManifest.xml
@@ -16,7 +16,8 @@
<!-- package name must be unique so suffix with "tests" so package loader doesn't ignore us -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.connectivitymanagertest">
+ package="com.android.connectivitymanagertest"
+ android:sharedUserId="com.android.uid.test">
<!-- We add an application tag here just so that we can indicate that
this package needs to link against the android.test library,
@@ -67,5 +68,9 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
+ <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
+ <uses-permission android:name="android.permission.DEVICE_POWER" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
</manifest>
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java
index 47f208a..5b76e39 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java
@@ -19,8 +19,8 @@
import android.os.Bundle;
import android.test.InstrumentationTestRunner;
import android.test.InstrumentationTestSuite;
-import android.util.Log;
import com.android.connectivitymanagertest.stress.WifiApStress;
+import com.android.connectivitymanagertest.stress.WifiStressTest;
import junit.framework.TestSuite;
@@ -34,10 +34,18 @@
*/
public class ConnectivityManagerStressTestRunner extends InstrumentationTestRunner {
+ public int mSoftapIterations = 100;
+ public int mScanIterations = 100;
+ public int mReconnectIterations = 100;
+ public int mSleepTime = 30 * 1000; // default sleep time is 30 seconds
+ public String mReconnectSsid = "securenetdhcp";
+ public String mReconnectPassword = "androidwifi";
+
@Override
public TestSuite getAllTests() {
TestSuite suite = new InstrumentationTestSuite(this);
suite.addTestSuite(WifiApStress.class);
+ suite.addTestSuite(WifiStressTest.class);
return suite;
}
@@ -49,14 +57,46 @@
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
- String stressValue = (String) icicle.get("stressnum");
- if (stressValue != null) {
- int iteration = Integer.parseInt(stressValue);
+ String valueStr = (String) icicle.get("softap_iterations");
+ if (valueStr != null) {
+ int iteration = Integer.parseInt(valueStr);
if (iteration > 0) {
- numStress = iteration;
+ mSoftapIterations = iteration;
+ }
+ }
+
+ String scanIterationStr = (String) icicle.get("scan_iterations");
+ if (scanIterationStr != null) {
+ int scanIteration = Integer.parseInt(scanIterationStr);
+ if (scanIteration > 0) {
+ mScanIterations = scanIteration;
+ }
+ }
+
+ String ssidStr= (String) icicle.get("reconnect_ssid");
+ if (ssidStr != null) {
+ mReconnectSsid = ssidStr;
+ }
+
+ String passwordStr = (String) icicle.get("reconnect_password");
+ if (passwordStr != null) {
+ mReconnectPassword = passwordStr;
+ }
+
+ String reconnectStr = (String) icicle.get("reconnect_iterations");
+ if (reconnectStr != null) {
+ int iteration = Integer.parseInt(reconnectStr);
+ if (iteration > 0) {
+ mReconnectIterations = iteration;
+ }
+ }
+
+ String sleepTimeStr = (String) icicle.get("sleep_time");
+ if (sleepTimeStr != null) {
+ int sleepTime = Integer.parseInt(sleepTimeStr);
+ if (sleepTime > 0) {
+ mSleepTime = 1000 * sleepTime;
}
}
}
-
- public int numStress = 100;
}
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
index 2888696..af74c6f 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
@@ -76,6 +76,7 @@
public String mBssid;
public String mPowerSsid = "GoogleGuest"; //Default power SSID
private Context mContext;
+ public boolean scanResultAvailable = false;
/*
* Control Wifi States
@@ -142,6 +143,7 @@
String action = intent.getAction();
Log.v("WifiReceiver", "onReceive() is calleld with " + intent);
if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
+ log("scan results are available");
notifyScanResult();
} else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
mWifiNetworkInfo =
@@ -174,6 +176,7 @@
public ConnectivityManagerTestActivity() {
mState = State.UNKNOWN;
+ scanResultAvailable = false;
}
@Override
@@ -267,6 +270,7 @@
private void notifyScanResult() {
synchronized (this) {
log("notify that scan results are available");
+ scanResultAvailable = true;
this.notify();
}
}
@@ -328,6 +332,8 @@
long startTime = System.currentTimeMillis();
while (true) {
if ((System.currentTimeMillis() - startTime) > timeout) {
+ log("waitForNetworkState time out, the state of network type " + networkType +
+ " is: " + mCM.getNetworkInfo(networkType).getState());
if (mCM.getNetworkInfo(networkType).getState() != expectedState) {
return false;
} else {
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
index cc53ddc..21ab0e6 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
@@ -19,25 +19,36 @@
import com.android.connectivitymanagertest.ConnectivityManagerStressTestRunner;
import com.android.connectivitymanagertest.ConnectivityManagerTestActivity;
-import com.android.connectivitymanagertest.ConnectivityManagerTestRunner;
+import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.net.wifi.WifiConfiguration.AuthAlgorithm;
+import android.net.wifi.WifiManager;
+import android.os.Environment;
+import android.os.PowerManager;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.LargeTest;
import android.util.Log;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+
/**
* Stress the wifi driver as access point.
*/
public class WifiApStress
extends ActivityInstrumentationTestCase2<ConnectivityManagerTestActivity> {
private final static String TAG = "WifiApStress";
- private ConnectivityManagerTestActivity mAct;
private static String NETWORK_ID = "AndroidAPTest";
private static String PASSWD = "androidwifi";
- private int max_num;
+ private final static String OUTPUT_FILE = "WifiApStressOutput.txt";
+ private ConnectivityManagerTestActivity mAct;
+ private int iterations;
+ private PowerManager.WakeLock mWakelock = null;
+ private BufferedWriter mOutputWriter = null;
+ private int mLastIteration = 0;
public WifiApStress() {
super(ConnectivityManagerTestActivity.class);
@@ -47,11 +58,27 @@
public void setUp() throws Exception {
super.setUp();
mAct = getActivity();
- max_num = ((ConnectivityManagerStressTestRunner)getInstrumentation()).numStress;
+ ConnectivityManagerStressTestRunner mRunner =
+ (ConnectivityManagerStressTestRunner)getInstrumentation();
+ iterations = mRunner.mSoftapIterations;
+ PowerManager pm =
+ (PowerManager)mRunner.getContext().getSystemService(Context.POWER_SERVICE);
+ mWakelock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "wifiApStress");
+ mWakelock.acquire();
}
@Override
public void tearDown() throws Exception {
+ if (mWakelock != null) {
+ mWakelock.release();
+ }
+ // write the total number of iterations into output file
+ mOutputWriter = new BufferedWriter(new FileWriter(new File(
+ Environment.getExternalStorageDirectory(), OUTPUT_FILE)));
+ mOutputWriter.write(String.format("iteration %d out of %d"
+ + "\n", mLastIteration, iterations));
+ mOutputWriter.flush();
+ mOutputWriter.close();
super.tearDown();
}
@@ -67,15 +94,18 @@
if (mAct.mWifiManager.isWifiEnabled()) {
mAct.disableWifi();
}
- for (int i = 0; i < max_num; i++) {
+ int i;
+ for (i = 0; i < iterations; i++) {
Log.v(TAG, "iteration: " + i);
+ mLastIteration = i;
// enable Wifi tethering
assertTrue(mAct.mWifiManager.setWifiApEnabled(config, true));
// Wait for wifi ap state to be ENABLED
- assertTrue(mAct.waitForWifiAPState(mAct.mWifiManager.WIFI_AP_STATE_ENABLED,
- mAct.LONG_TIMEOUT));
+ assertTrue(mAct.waitForWifiAPState(WifiManager.WIFI_AP_STATE_ENABLED,
+ ConnectivityManagerTestActivity.LONG_TIMEOUT));
// Wait for wifi tethering result
- assertEquals(mAct.SUCCESS, mAct.waitForTetherStateChange(2*mAct.SHORT_TIMEOUT));
+ assertEquals(ConnectivityManagerTestActivity.SUCCESS,
+ mAct.waitForTetherStateChange(2*ConnectivityManagerTestActivity.SHORT_TIMEOUT));
// Allow the wifi tethering to be enabled for 10 seconds
try {
Thread.sleep(2 * ConnectivityManagerTestActivity.SHORT_TIMEOUT);
@@ -84,6 +114,9 @@
}
assertTrue(mAct.mWifiManager.setWifiApEnabled(config, false));
}
+ if (i == iterations) {
+ mLastIteration = iterations;
+ }
}
}
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
new file mode 100644
index 0000000..0756a72
--- /dev/null
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
@@ -0,0 +1,301 @@
+/*
+ * 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.connectivitymanagertest.stress;
+
+import com.android.connectivitymanagertest.ConnectivityManagerStressTestRunner;
+import com.android.connectivitymanagertest.ConnectivityManagerTestActivity;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo.State;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiConfiguration.IpAssignment;
+import android.net.wifi.WifiConfiguration.KeyMgmt;
+import android.net.wifi.WifiConfiguration.ProxySettings;
+import android.net.wifi.WifiManager;
+import android.os.Environment;
+import android.os.PowerManager;
+import android.os.SystemClock;
+import android.provider.Settings;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import android.util.Log;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Stress Wi-Fi connection, scanning and reconnection after sleep.
+ *
+ * To run this stress test suite, type
+ * adb shell am instrument -e class com.android.connectivitymanagertest.stress.WifiStressTest
+ * -w com.android.connectivitymanagertest/.ConnectivityManagerStressTestRunner
+ */
+public class WifiStressTest
+ extends ActivityInstrumentationTestCase2<ConnectivityManagerTestActivity> {
+ private final static String TAG = "WifiStressTest";
+
+ /**
+ * Wi-Fi idle time for default sleep policy
+ */
+ private final static long WIFI_IDLE_MS = 5 * 1000;
+
+ /**
+ * The delay for Wi-Fi to get into idle, after screen off + WIFI_IDEL_MS + WIFI_IDLE_DELAY
+ * the Wi-Fi should be in idle mode and device should be in cellular mode.
+ */
+ private final static long WIFI_IDLE_DELAY = 3 * 1000;
+
+ private final static String OUTPUT_FILE = "WifiStressTestOutput.txt";
+ private ConnectivityManagerTestActivity mAct;
+ private int mReconnectIterations;
+ private int mWifiSleepTime;
+ private int mScanIterations;
+ private String mSsid;
+ private String mPassword;
+ private ConnectivityManagerStressTestRunner mRunner;
+ private PowerManager.WakeLock wl = null;
+ private BufferedWriter mOutputWriter = null;
+
+ public WifiStressTest() {
+ super(ConnectivityManagerTestActivity.class);
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ mAct = getActivity();
+ mRunner = (ConnectivityManagerStressTestRunner) getInstrumentation();
+ mReconnectIterations = mRunner.mReconnectIterations;
+ mSsid = mRunner.mReconnectSsid;
+ mPassword = mRunner.mReconnectPassword;
+ mScanIterations = mRunner.mScanIterations;
+ mWifiSleepTime = mRunner.mSleepTime;
+ wl = null;
+ mOutputWriter = new BufferedWriter(new FileWriter(new File(
+ Environment.getExternalStorageDirectory(), OUTPUT_FILE), true));
+ if (!mAct.mWifiManager.isWifiEnabled()) {
+ if (!mAct.enableWifi()) {
+ tearDown();
+ fail("enable wifi failed.");
+ }
+ sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT,
+ "Interruped while waiting for wifi on");
+ }
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ log("tearDown()");
+ if ((wl != null) && wl.isHeld()) {
+ wl.release();
+ }
+ if (mOutputWriter != null) {
+ mOutputWriter.close();
+ }
+ super.tearDown();
+ }
+
+ private void writeOutput(String s) {
+ log("write message: " + s);
+ if (mOutputWriter == null) {
+ log("no writer attached to file " + OUTPUT_FILE);
+ return;
+ }
+ try {
+ mOutputWriter.write(s + "\n");
+ mOutputWriter.flush();
+ } catch (IOException e) {
+ log("failed to write output.");
+ }
+ }
+
+ private void turnScreenOff() {
+ log("Turn screen off");
+ if (wl != null) {
+ log("release wake lock");
+ wl.release();
+ }
+ PowerManager pm =
+ (PowerManager) mRunner.getContext().getSystemService(Context.POWER_SERVICE);
+ pm.goToSleep(SystemClock.uptimeMillis() + 50);
+ }
+
+ private void turnScreenOn() {
+ log("Turn screen on");
+ PowerManager pm =
+ (PowerManager)mRunner.getContext().getSystemService(Context.POWER_SERVICE);
+ wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP,
+ "wifiStressTest");
+ wl.acquire();
+ }
+
+ public void log(String message) {
+ Log.v(TAG, message);
+ }
+
+ private void sleep(long sometime, String errorMsg) {
+ try {
+ Thread.sleep(sometime);
+ } catch (InterruptedException e) {
+ fail(errorMsg);
+ }
+ }
+
+ /**
+ * Stress Wifi Scanning
+ * TODO: test the scanning quality for each frequency band
+ */
+ @LargeTest
+ public void testWifiScanning() {
+ int scanTimeSum = 0;
+ int i;
+ int averageScanTime = 0;
+ int ssidAppearInScanResultsCount = 0; // count times of given ssid appear in scan results.
+ for (i = 0; i < mScanIterations; i++) {
+ log("testWifiScanning: iteration: " + i);
+ writeOutput(String.format("scan iteration %d out of %d",
+ i, mScanIterations));
+ writeOutput(String.format("average scanning time is %d", averageScanTime));
+ writeOutput(String.format("ssid appear %d out of %d scan iterations",
+ ssidAppearInScanResultsCount, mScanIterations));
+ long startTime = System.currentTimeMillis();
+ mAct.scanResultAvailable = false;
+ assertTrue("start scan failed", mAct.mWifiManager.startScanActive());
+ while (true) {
+ if ((System.currentTimeMillis() - startTime) >
+ ConnectivityManagerTestActivity.WIFI_SCAN_TIMEOUT) {
+ fail("Wifi scanning takes more than " +
+ ConnectivityManagerTestActivity.WIFI_SCAN_TIMEOUT + " ms");
+ }
+ synchronized(mAct) {
+ try {
+ mAct.wait(ConnectivityManagerTestActivity.WAIT_FOR_SCAN_RESULT);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ if (mAct.scanResultAvailable) {
+ long scanTime = (System.currentTimeMillis() - startTime);
+ scanTimeSum += scanTime;
+ averageScanTime = scanTimeSum/mScanIterations;
+ log("average scanning time: " + averageScanTime);
+ break;
+ }
+ }
+ }
+ if ((mAct.mWifiManager.getScanResults() == null) ||
+ (mAct.mWifiManager.getScanResults().size() <= 0)) {
+ fail("Scan results are empty ");
+ }
+
+ List<ScanResult> netList = mAct.mWifiManager.getScanResults();
+ if (netList != null) {
+ log("size of scan result list: " + netList.size());
+ for (int s = 0; s < netList.size(); s++) {
+ ScanResult sr= netList.get(s);
+ log(String.format("scan result for %s is: %s", sr.SSID, sr.toString()));
+ log(String.format("signal level for %s is %d ", sr.SSID, sr.level));
+ if (sr.SSID.equals(mSsid)) {
+ ssidAppearInScanResultsCount += 1;
+ log("Number of times " + mSsid + " appear in the scan list: " +
+ ssidAppearInScanResultsCount);
+ break;
+ }
+ }
+ }
+ }
+ if (i == mScanIterations) {
+ writeOutput(String.format("scan iteration %d out of %d",
+ i, mScanIterations));
+ writeOutput(String.format("average scanning time is %d", averageScanTime));
+ writeOutput(String.format("ssid appear %d out of %d scan iterations",
+ ssidAppearInScanResultsCount, mScanIterations));
+ }
+ }
+
+ // Stress Wifi reconnection to secure net after sleep
+ @LargeTest
+ public void testWifiReconnectionAfterSleep() {
+ int value = Settings.System.getInt(mRunner.getContext().getContentResolver(),
+ Settings.System.WIFI_SLEEP_POLICY, -1);
+ if (value < 0) {
+ Settings.System.putInt(mRunner.getContext().getContentResolver(),
+ Settings.System.WIFI_SLEEP_POLICY, Settings.System.WIFI_SLEEP_POLICY_DEFAULT);
+ log("set wifi sleep policy to default value");
+ }
+ Settings.Secure.putLong(mRunner.getContext().getContentResolver(),
+ Settings.Secure.WIFI_IDLE_MS, WIFI_IDLE_MS);
+
+ // Connect to a Wi-Fi network
+ turnScreenOn();
+ WifiConfiguration config = new WifiConfiguration();
+ config.SSID = mSsid;
+ config.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
+ if (mPassword.matches("[0-9A-Fa-f]{64}")) {
+ config.preSharedKey = mPassword;
+ } else {
+ config.preSharedKey = '"' + mPassword + '"';
+ }
+ config.ipAssignment = IpAssignment.DHCP;
+ config.proxySettings = ProxySettings.NONE;
+
+ assertTrue("Failed to connect to Wi-Fi network: " + mSsid,
+ mAct.connectToWifiWithConfiguration(config));
+ assertTrue(mAct.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
+ ConnectivityManagerTestActivity.SHORT_TIMEOUT));
+ assertTrue(mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+ ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ int i;
+ for (i = 0; i < mReconnectIterations; i++) {
+ // 1. Put device into sleep
+ // 2. Wait for the device to sleep for sometime, very 3G is connected
+ // 3. Wake up the device
+ writeOutput(String.format("reconnection after sleep iteration %d out of %d",
+ i, mReconnectIterations));
+ log("iteration: " + i);
+ turnScreenOff();
+ PowerManager pm =
+ (PowerManager)mRunner.getContext().getSystemService(Context.POWER_SERVICE);
+ assertFalse(pm.isScreenOn());
+ sleep(WIFI_IDLE_MS + WIFI_IDLE_DELAY, "Interruped while wait for wifi to be idle");
+ assertTrue("Wait for Wi-Fi to idle timeout",
+ mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED,
+ ConnectivityManagerTestActivity.SHORT_TIMEOUT));
+ assertTrue("Wait for cellular connection timeout",
+ mAct.waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
+ ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ sleep(mWifiSleepTime + WIFI_IDLE_DELAY, "Interrupted while device is in sleep mode");
+ // Turn screen on again
+ turnScreenOn();
+ assertTrue("Wait for Wi-Fi enable timeout after wake up",
+ mAct.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
+ ConnectivityManagerTestActivity.SHORT_TIMEOUT));
+ assertTrue("Wait for Wi-Fi connection timeout after wake up",
+ mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+ ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ }
+ if (i == mReconnectIterations) {
+ writeOutput(String.format("reconnection after sleep iteration %d out of %d",
+ i, mReconnectIterations));
+ }
+ }
+}
diff --git a/data/keyboards/Generic.kcm b/data/keyboards/Generic.kcm
index 24b485d..14d7c80 100644
--- a/data/keyboards/Generic.kcm
+++ b/data/keyboards/Generic.kcm
@@ -42,7 +42,9 @@
label: 'C'
base: 'c'
shift, capslock: 'C'
- ctrl, alt, meta: none
+ alt: '\u00e7'
+ shift+alt: '\u00c7'
+ ctrl, meta: none
}
key D {
@@ -56,7 +58,8 @@
label: 'E'
base: 'e'
shift, capslock: 'E'
- ctrl, alt, meta: none
+ alt: '\u0301'
+ ctrl, meta: none
}
key F {
@@ -84,7 +87,8 @@
label: 'I'
base: 'i'
shift, capslock: 'I'
- ctrl, alt, meta: none
+ alt: '\u0302'
+ ctrl, meta: none
}
key J {
@@ -119,7 +123,8 @@
label: 'N'
base: 'n'
shift, capslock: 'N'
- ctrl, alt, meta: none
+ alt: '\u0303'
+ ctrl, meta: none
}
key O {
@@ -154,7 +159,8 @@
label: 'S'
base: 's'
shift, capslock: 'S'
- ctrl, alt, meta: none
+ alt: '\u00df'
+ ctrl, meta: none
}
key T {
@@ -168,7 +174,8 @@
label: 'U'
base: 'u'
shift, capslock: 'U'
- ctrl, alt, meta: none
+ alt: '\u0308'
+ ctrl, meta: none
}
key V {
@@ -253,6 +260,7 @@
base: '6'
shift: '^'
ctrl, alt, meta: none
+ alt+shift: '\u0302'
}
key 7 {
@@ -279,7 +287,8 @@
key SPACE {
label: ' '
base: ' '
- ctrl, alt, meta: none
+ ctrl, alt: none
+ meta: fallback SEARCH
}
key ENTER {
@@ -291,7 +300,8 @@
key TAB {
label: '\t'
base: '\t'
- ctrl, alt, meta: none
+ ctrl, alt: none
+ meta: fallback APP_SWITCH
}
key COMMA {
@@ -319,7 +329,9 @@
label, number: '`'
base: '`'
shift: '~'
- ctrl, alt, meta: none
+ alt: '\u0300'
+ alt+shift: '\u0303'
+ ctrl, meta: none
}
key MINUS {
@@ -525,3 +537,11 @@
label, number: '+'
base: '+'
}
+
+### Non-printing keys ###
+
+key ESCAPE {
+ base: fallback BACK
+ meta: fallback HOME
+ alt: fallback MENU
+}
diff --git a/data/keyboards/Vendor_05ac_Product_0239.kl b/data/keyboards/Vendor_05ac_Product_0239.kl
index 5234d58..6bd3753 100644
--- a/data/keyboards/Vendor_05ac_Product_0239.kl
+++ b/data/keyboards/Vendor_05ac_Product_0239.kl
@@ -104,7 +104,7 @@
key 113 VOLUME_MUTE
key 114 VOLUME_DOWN
key 115 VOLUME_UP
-# key 120 switch applications
+key 120 APP_SWITCH
key 125 META_LEFT
key 126 META_RIGHT
key 161 MEDIA_EJECT
diff --git a/data/keyboards/Vendor_22b8_Product_093d.kl b/data/keyboards/Vendor_22b8_Product_093d.kl
index 87b3c32..2749c5b 100644
--- a/data/keyboards/Vendor_22b8_Product_093d.kl
+++ b/data/keyboards/Vendor_22b8_Product_093d.kl
@@ -12,6 +12,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+#
+# Motorola Bluetooth Wireless Keyboard.
+#
+
key 1 BACK
key 2 1
key 3 2
diff --git a/data/keyboards/Virtual.kcm b/data/keyboards/Virtual.kcm
index 8d3c7ac..0ce4a68 100644
--- a/data/keyboards/Virtual.kcm
+++ b/data/keyboards/Virtual.kcm
@@ -39,7 +39,9 @@
label: 'C'
base: 'c'
shift, capslock: 'C'
- ctrl, alt, meta: none
+ alt: '\u00e7'
+ shift+alt: '\u00c7'
+ ctrl, meta: none
}
key D {
@@ -53,7 +55,8 @@
label: 'E'
base: 'e'
shift, capslock: 'E'
- ctrl, alt, meta: none
+ alt: '\u0301'
+ ctrl, meta: none
}
key F {
@@ -81,7 +84,8 @@
label: 'I'
base: 'i'
shift, capslock: 'I'
- ctrl, alt, meta: none
+ alt: '\u0302'
+ ctrl, meta: none
}
key J {
@@ -116,7 +120,8 @@
label: 'N'
base: 'n'
shift, capslock: 'N'
- ctrl, alt, meta: none
+ alt: '\u0303'
+ ctrl, meta: none
}
key O {
@@ -151,7 +156,8 @@
label: 'S'
base: 's'
shift, capslock: 'S'
- ctrl, alt, meta: none
+ alt: '\u00df'
+ ctrl, meta: none
}
key T {
@@ -165,7 +171,8 @@
label: 'U'
base: 'u'
shift, capslock: 'U'
- ctrl, alt, meta: none
+ alt: '\u0308'
+ ctrl, meta: none
}
key V {
@@ -250,6 +257,7 @@
base: '6'
shift: '^'
ctrl, alt, meta: none
+ alt+shift: '\u0302'
}
key 7 {
@@ -276,7 +284,8 @@
key SPACE {
label: ' '
base: ' '
- ctrl, alt, meta: none
+ ctrl, alt: none
+ meta: fallback SEARCH
}
key ENTER {
@@ -288,7 +297,8 @@
key TAB {
label: '\t'
base: '\t'
- ctrl, alt, meta: none
+ ctrl, alt: none
+ meta: fallback APP_SWITCH
}
key COMMA {
@@ -316,7 +326,9 @@
label, number: '`'
base: '`'
shift: '~'
- ctrl, alt, meta: none
+ alt: '\u0300'
+ alt+shift: '\u0303'
+ ctrl, meta: none
}
key MINUS {
@@ -522,3 +534,11 @@
label, number: '+'
base: '+'
}
+
+### Non-printing keys ###
+
+key ESCAPE {
+ base: fallback BACK
+ meta: fallback HOME
+ alt: fallback MENU
+}
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index 8450c3a..66f8f70 100644
--- a/graphics/java/android/graphics/BitmapFactory.java
+++ b/graphics/java/android/graphics/BitmapFactory.java
@@ -210,7 +210,6 @@
* expense of the decoding speed. Currently the field only affects JPEG
* decode, in the case of which a more accurate, but slightly slower,
* IDCT method will be used instead.
- * @hide
*/
public boolean inPreferQualityOverSpeed;
diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h
index c446633..aa65d93 100644
--- a/include/ui/GraphicBuffer.h
+++ b/include/ui/GraphicBuffer.h
@@ -91,12 +91,15 @@
status_t lock(uint32_t usage, const Rect& rect, void** vaddr);
status_t lock(GGLSurface* surface, uint32_t usage);
status_t unlock();
-
+
android_native_buffer_t* getNativeBuffer() const;
void setIndex(int index);
int getIndex() const;
+ // for debugging
+ static void dumpAllocationsToSystemLog();
+
private:
virtual ~GraphicBuffer();
diff --git a/include/ui/GraphicBufferAllocator.h b/include/ui/GraphicBufferAllocator.h
index 54b8236..dffa788 100644
--- a/include/ui/GraphicBufferAllocator.h
+++ b/include/ui/GraphicBufferAllocator.h
@@ -68,6 +68,7 @@
status_t free(buffer_handle_t handle);
void dump(String8& res) const;
+ static void dumpToSystemLog();
private:
struct alloc_rec_t {
diff --git a/include/ui/InputDispatcher.h b/include/ui/InputDispatcher.h
index b621680..7305601 100644
--- a/include/ui/InputDispatcher.h
+++ b/include/ui/InputDispatcher.h
@@ -306,9 +306,10 @@
virtual bool interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
const KeyEvent* keyEvent, uint32_t policyFlags) = 0;
- /* Allows the policy a chance to perform default processing for an unhandled key. */
+ /* Allows the policy a chance to perform default processing for an unhandled key.
+ * Returns an alternate keycode to redispatch as a fallback, or 0 to give up. */
virtual bool dispatchUnhandledKey(const sp<InputChannel>& inputChannel,
- const KeyEvent* keyEvent, uint32_t policyFlags) = 0;
+ const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) = 0;
/* Notifies the policy about switch events.
*/
@@ -735,6 +736,7 @@
CANCEL_ALL_EVENTS = 0,
CANCEL_POINTER_EVENTS = 1,
CANCEL_NON_POINTER_EVENTS = 2,
+ CANCEL_FALLBACK_EVENTS = 3,
};
InputState();
@@ -771,6 +773,7 @@
int32_t source;
int32_t keyCode;
int32_t scanCode;
+ int32_t flags;
nsecs_t downTime;
};
@@ -790,7 +793,10 @@
Vector<KeyMemento> mKeyMementos;
Vector<MotionMemento> mMotionMementos;
- static bool shouldCancelEvent(int32_t eventSource, CancelationOptions options);
+ static bool shouldCancelKey(const KeyMemento& memento,
+ CancelationOptions options);
+ static bool shouldCancelMotion(const MotionMemento& memento,
+ CancelationOptions options);
};
/* Manages the dispatch state associated with a single input channel. */
diff --git a/include/ui/InputReader.h b/include/ui/InputReader.h
index 8ec5421..b466ff1 100644
--- a/include/ui/InputReader.h
+++ b/include/ui/InputReader.h
@@ -402,7 +402,6 @@
} mLocked;
void initializeLocked();
- void initializeLedStateLocked(LockedState::LedState& ledState, int32_t led);
void configureParameters();
void dumpParameters(String8& dump);
@@ -414,6 +413,8 @@
ssize_t findKeyDownLocked(int32_t scanCode);
+ void resetLedStateLocked();
+ void initializeLedStateLocked(LockedState::LedState& ledState, int32_t led);
void updateLedStateLocked(bool reset);
void updateLedStateForModifierLocked(LockedState::LedState& ledState, int32_t led,
int32_t modifier, bool reset);
diff --git a/include/ui/InputTransport.h b/include/ui/InputTransport.h
index 7efb6cc..119db81 100644
--- a/include/ui/InputTransport.h
+++ b/include/ui/InputTransport.h
@@ -256,7 +256,7 @@
* Returns WOULD_BLOCK if there is no signal present.
* Other errors probably indicate that the channel is broken.
*/
- status_t receiveFinishedSignal(bool& outHandled);
+ status_t receiveFinishedSignal(bool* outHandled);
private:
sp<InputChannel> mChannel;
diff --git a/include/ui/KeyCharacterMap.h b/include/ui/KeyCharacterMap.h
index a1ccb37..10a3810 100644
--- a/include/ui/KeyCharacterMap.h
+++ b/include/ui/KeyCharacterMap.h
@@ -44,6 +44,12 @@
KEYBOARD_TYPE_SPECIAL_FUNCTION = 5,
};
+ // Substitute key code and meta state for fallback action.
+ struct FallbackAction {
+ int32_t keyCode;
+ int32_t metaState;
+ };
+
~KeyCharacterMap();
static status_t load(const String8& filename, KeyCharacterMap** outMap);
@@ -67,6 +73,13 @@
*/
char16_t getCharacter(int32_t keyCode, int32_t metaState) const;
+ /* Gets the fallback action to use by default if the application does not
+ * handle the specified key.
+ * Returns true if an action was available, false if none.
+ */
+ bool getFallbackAction(int32_t keyCode, int32_t metaState,
+ FallbackAction* outFallbackAction) const;
+
/* Gets the first matching Unicode character that can be generated by the key,
* preferring the one with the specified meta key modifiers.
* Returns 0 if no matching character is generated.
@@ -155,6 +168,10 @@
KeyCharacterMap();
+ bool getKey(int32_t keyCode, const Key** outKey) const;
+ bool getKeyBehavior(int32_t keyCode, int32_t metaState,
+ const Key** outKey, const Behavior** outBehavior) const;
+
bool findKey(char16_t ch, int32_t* outKeyCode, int32_t* outMetaState) const;
static void addKey(Vector<KeyEvent>& outEvents,
diff --git a/include/ui/KeycodeLabels.h b/include/ui/KeycodeLabels.h
index be7db1f..9b1a897 100755
--- a/include/ui/KeycodeLabels.h
+++ b/include/ui/KeycodeLabels.h
@@ -211,6 +211,7 @@
{ "PROG_GREEN", 184 },
{ "PROG_YELLOW", 185 },
{ "PROG_BLUE", 186 },
+ { "APP_SWITCH", 187 },
// NOTE: If you add a new keycode here you must also add it to several other files.
// Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index fc14777..1a89ca0 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -954,11 +954,11 @@
mSnapshot->region && mesh->hasEmptyQuads) {
const size_t count = mesh->quads.size();
for (size_t i = 0; i < count; i++) {
- Rect bounds = mesh->quads.itemAt(i);
+ const Rect& bounds = mesh->quads.itemAt(i);
if (pureTranslate) {
const float x = (int) floorf(bounds.left + 0.5f);
const float y = (int) floorf(bounds.top + 0.5f);
- dirtyLayer(x, y, x + bounds.getWidth(), y + bounds.getBottom(),
+ dirtyLayer(x, y, x + bounds.getWidth(), y + bounds.getHeight(),
*mSnapshot->transform);
} else {
dirtyLayer(bounds.left, bounds.top, bounds.right, bounds.bottom,
diff --git a/libs/hwui/Patch.cpp b/libs/hwui/Patch.cpp
index 17b1d86..e5cb67b 100644
--- a/libs/hwui/Patch.cpp
+++ b/libs/hwui/Patch.cpp
@@ -35,7 +35,7 @@
mXCount(xCount), mYCount(yCount), mEmptyQuads(emptyQuads) {
// Initialized with the maximum number of vertices we will need
// 2 triangles per patch, 3 vertices per triangle
- const int maxVertices = ((xCount + 1) * (yCount + 1) - emptyQuads) * 2 * 3;
+ uint32_t maxVertices = ((xCount + 1) * (yCount + 1) - emptyQuads) * 2 * 3;
mVertices = new TextureVertex[maxVertices];
mUploaded = false;
@@ -160,7 +160,7 @@
float y2 = 0.0f;
if (i & 1) {
const float segment = stepY - previousStepY;
- y2 = y1 + segment * stretchY;
+ y2 = y1 + floorf(segment * stretchY + 0.5f);
} else {
y2 = y1 + stepY - previousStepY;
}
@@ -206,7 +206,7 @@
float x2 = 0.0f;
if (i & 1) {
const float segment = stepX - previousStepX;
- x2 = x1 + segment * stretchX;
+ x2 = x1 + floorf(segment * stretchX + 0.5f);
} else {
x2 = x1 + stepX - previousStepX;
}
@@ -226,7 +226,7 @@
void Patch::generateQuad(TextureVertex*& vertex, float x1, float y1, float x2, float y2,
float u1, float v1, float u2, float v2, uint32_t& quadCount) {
const uint32_t oldQuadCount = quadCount;
- const bool valid = fabs(x2 - x1) > 0.9999f && fabs(y2 - y1) > 0.9999f;
+ const bool valid = x2 - x1 > 0.9999f && y2 - y1 > 0.9999f;
if (valid) {
quadCount++;
}
diff --git a/libs/hwui/Patch.h b/libs/hwui/Patch.h
index 16ad86d..0f0ffa2 100644
--- a/libs/hwui/Patch.h
+++ b/libs/hwui/Patch.h
@@ -52,9 +52,7 @@
GLuint meshBuffer;
uint32_t verticesCount;
bool hasEmptyQuads;
-#if RENDER_LAYERS_AS_REGIONS
Vector<Rect> quads;
-#endif
private:
TextureVertex* mVertices;
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index 6587b51..d4edafd 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -378,6 +378,12 @@
static BCCvoid* symbolLookup(BCCvoid* pContext, const BCCchar* name) {
const ScriptCState::SymbolTable_t *sym;
ScriptC *s = (ScriptC *)pContext;
+ if (!strcmp(name, "__isThreadable")) {
+ return (BCCvoid*) s->mEnviroment.mIsThreadable;
+ } else if (!strcmp(name, "__clearThreadable")) {
+ s->mEnviroment.mIsThreadable = false;
+ return NULL;
+ }
sym = ScriptCState::lookupSymbol(name);
if (!sym) {
sym = ScriptCState::lookupSymbolCL(name);
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index 436e064..97312a6 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -114,6 +114,11 @@
return mInitCheck;
}
+void GraphicBuffer::dumpAllocationsToSystemLog()
+{
+ GraphicBufferAllocator::dumpToSystemLog();
+}
+
android_native_buffer_t* GraphicBuffer::getNativeBuffer() const
{
return static_cast<android_native_buffer_t*>(
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index d51664d..fa46ab7 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -73,6 +73,13 @@
result.append(buffer);
}
+void GraphicBufferAllocator::dumpToSystemLog()
+{
+ String8 s;
+ GraphicBufferAllocator::getInstance().dump(s);
+ LOGD("%s", s.string());
+}
+
status_t GraphicBufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat format,
int usage, buffer_handle_t* handle, int32_t* stride)
{
@@ -104,10 +111,6 @@
rec.usage = usage;
rec.size = h * stride[0] * bytesPerPixel(format);
list.add(*handle, rec);
- } else {
- String8 s;
- dump(s);
- LOGD("%s", s.string());
}
return err;
diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp
index f1223f1..1f6a920 100644
--- a/libs/ui/InputDispatcher.cpp
+++ b/libs/ui/InputDispatcher.cpp
@@ -1884,7 +1884,7 @@
}
bool handled = false;
- status_t status = connection->inputPublisher.receiveFinishedSignal(handled);
+ status_t status = connection->inputPublisher.receiveFinishedSignal(&handled);
if (status) {
LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
connection->getInputChannelName(), status);
@@ -3039,21 +3039,57 @@
sp<Connection> connection = commandEntry->connection;
bool handled = commandEntry->handled;
- if (!handled && !connection->outboundQueue.isEmpty()) {
+ if (!connection->outboundQueue.isEmpty()) {
DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
if (dispatchEntry->inProgress
&& dispatchEntry->hasForegroundTarget()
&& dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
- KeyEvent event;
- initializeKeyEvent(&event, keyEntry);
+ if (!(keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK)) {
+ if (handled) {
+ // If the application handled a non-fallback key, then immediately
+ // cancel all fallback keys previously dispatched to the application.
+ // This behavior will prevent chording with fallback keys (so they cannot
+ // be used as modifiers) but it will ensure that fallback keys do not
+ // get stuck. This takes care of the case where the application does not handle
+ // the original DOWN so we generate a fallback DOWN but it does handle
+ // the original UP in which case we would not generate the fallback UP.
+ synthesizeCancelationEventsForConnectionLocked(connection,
+ InputState::CANCEL_FALLBACK_EVENTS,
+ "Application handled a non-fallback event.");
+ } else {
+ // If the application did not handle a non-fallback key, then ask
+ // the policy what to do with it. We might generate a fallback key
+ // event here.
+ KeyEvent event;
+ initializeKeyEvent(&event, keyEntry);
- mLock.unlock();
+ mLock.unlock();
- mPolicy->dispatchUnhandledKey(connection->inputChannel,
- &event, keyEntry->policyFlags);
+ bool fallback = mPolicy->dispatchUnhandledKey(connection->inputChannel,
+ &event, keyEntry->policyFlags, &event);
- mLock.lock();
+ mLock.lock();
+
+ if (fallback) {
+ // Restart the dispatch cycle using the fallback key.
+ keyEntry->eventTime = event.getEventTime();
+ keyEntry->deviceId = event.getDeviceId();
+ keyEntry->source = event.getSource();
+ keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
+ keyEntry->keyCode = event.getKeyCode();
+ keyEntry->scanCode = event.getScanCode();
+ keyEntry->metaState = event.getMetaState();
+ keyEntry->repeatCount = event.getRepeatCount();
+ keyEntry->downTime = event.getDownTime();
+ keyEntry->syntheticRepeat = false;
+
+ dispatchEntry->inProgress = false;
+ startDispatchCycleLocked(now(), connection);
+ return;
+ }
+ }
+ }
}
}
@@ -3371,6 +3407,7 @@
memento.source = entry->source;
memento.keyCode = entry->keyCode;
memento.scanCode = entry->scanCode;
+ memento.flags = entry->flags;
memento.downTime = entry->downTime;
return CONSISTENT;
}
@@ -3453,10 +3490,10 @@
CancelationOptions options) {
for (size_t i = 0; i < mKeyMementos.size(); ) {
const KeyMemento& memento = mKeyMementos.itemAt(i);
- if (shouldCancelEvent(memento.source, options)) {
+ if (shouldCancelKey(memento, options)) {
outEvents.push(allocator->obtainKeyEntry(currentTime,
memento.deviceId, memento.source, 0,
- AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_CANCELED,
+ AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
mKeyMementos.removeAt(i);
} else {
@@ -3466,7 +3503,7 @@
for (size_t i = 0; i < mMotionMementos.size(); ) {
const MotionMemento& memento = mMotionMementos.itemAt(i);
- if (shouldCancelEvent(memento.source, options)) {
+ if (shouldCancelMotion(memento, options)) {
outEvents.push(allocator->obtainMotionEntry(currentTime,
memento.deviceId, memento.source, 0,
AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
@@ -3502,15 +3539,30 @@
}
}
-bool InputDispatcher::InputState::shouldCancelEvent(int32_t eventSource,
+bool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento,
CancelationOptions options) {
switch (options) {
- case CANCEL_POINTER_EVENTS:
- return eventSource & AINPUT_SOURCE_CLASS_POINTER;
+ case CANCEL_ALL_EVENTS:
case CANCEL_NON_POINTER_EVENTS:
- return !(eventSource & AINPUT_SOURCE_CLASS_POINTER);
- default:
return true;
+ case CANCEL_FALLBACK_EVENTS:
+ return memento.flags & AKEY_EVENT_FLAG_FALLBACK;
+ default:
+ return false;
+ }
+}
+
+bool InputDispatcher::InputState::shouldCancelMotion(const MotionMemento& memento,
+ CancelationOptions options) {
+ switch (options) {
+ case CANCEL_ALL_EVENTS:
+ return true;
+ case CANCEL_POINTER_EVENTS:
+ return memento.source & AINPUT_SOURCE_CLASS_POINTER;
+ case CANCEL_NON_POINTER_EVENTS:
+ return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
+ default:
+ return false;
}
}
diff --git a/libs/ui/InputReader.cpp b/libs/ui/InputReader.cpp
index 9cc96ad..51ed09f 100644
--- a/libs/ui/InputReader.cpp
+++ b/libs/ui/InputReader.cpp
@@ -745,17 +745,6 @@
void KeyboardInputMapper::initializeLocked() {
mLocked.metaState = AMETA_NONE;
mLocked.downTime = 0;
-
- initializeLedStateLocked(mLocked.capsLockLedState, LED_CAPSL);
- initializeLedStateLocked(mLocked.numLockLedState, LED_NUML);
- initializeLedStateLocked(mLocked.scrollLockLedState, LED_SCROLLL);
-
- updateLedStateLocked(true);
-}
-
-void KeyboardInputMapper::initializeLedStateLocked(LockedState::LedState& ledState, int32_t led) {
- ledState.avail = getEventHub()->hasLed(getDeviceId(), led);
- ledState.on = false;
}
uint32_t KeyboardInputMapper::getSources() {
@@ -786,6 +775,12 @@
// Configure basic parameters.
configureParameters();
+
+ // Reset LEDs.
+ {
+ AutoMutex _l(mLock);
+ resetLedStateLocked();
+ }
}
void KeyboardInputMapper::configureParameters() {
@@ -813,6 +808,7 @@
// Synthesize key up event on reset if keys are currently down.
if (mLocked.keyDowns.isEmpty()) {
initializeLocked();
+ resetLedStateLocked();
break; // done
}
@@ -953,6 +949,19 @@
} // release lock
}
+void KeyboardInputMapper::resetLedStateLocked() {
+ initializeLedStateLocked(mLocked.capsLockLedState, LED_CAPSL);
+ initializeLedStateLocked(mLocked.numLockLedState, LED_NUML);
+ initializeLedStateLocked(mLocked.scrollLockLedState, LED_SCROLLL);
+
+ updateLedStateLocked(true);
+}
+
+void KeyboardInputMapper::initializeLedStateLocked(LockedState::LedState& ledState, int32_t led) {
+ ledState.avail = getEventHub()->hasLed(getDeviceId(), led);
+ ledState.on = false;
+}
+
void KeyboardInputMapper::updateLedStateLocked(bool reset) {
updateLedStateForModifierLocked(mLocked.capsLockLedState, LED_CAPSL,
AMETA_CAPS_LOCK_ON, reset);
@@ -966,7 +975,7 @@
int32_t led, int32_t modifier, bool reset) {
if (ledState.avail) {
bool desiredState = (mLocked.metaState & modifier) != 0;
- if (ledState.on != desiredState) {
+ if (reset || ledState.on != desiredState) {
getEventHub()->setLedState(getDeviceId(), led, desiredState);
ledState.on = desiredState;
}
diff --git a/libs/ui/InputTransport.cpp b/libs/ui/InputTransport.cpp
index 1885691..83d9556 100644
--- a/libs/ui/InputTransport.cpp
+++ b/libs/ui/InputTransport.cpp
@@ -501,7 +501,7 @@
return mChannel->sendSignal(INPUT_SIGNAL_DISPATCH);
}
-status_t InputPublisher::receiveFinishedSignal(bool& outHandled) {
+status_t InputPublisher::receiveFinishedSignal(bool* outHandled) {
#if DEBUG_TRANSPORT_ACTIONS
LOGD("channel '%s' publisher ~ receiveFinishedSignal",
mChannel->getName().string());
@@ -510,13 +510,13 @@
char signal;
status_t result = mChannel->receiveSignal(& signal);
if (result) {
- outHandled = false;
+ *outHandled = false;
return result;
}
if (signal == INPUT_SIGNAL_FINISHED_HANDLED) {
- outHandled = true;
+ *outHandled = true;
} else if (signal == INPUT_SIGNAL_FINISHED_UNHANDLED) {
- outHandled = false;
+ *outHandled = false;
} else {
LOGE("channel '%s' publisher ~ Received unexpected signal '%c' from consumer",
mChannel->getName().string(), signal);
diff --git a/libs/ui/KeyCharacterMap.cpp b/libs/ui/KeyCharacterMap.cpp
index e689c4b..9bfa8f6 100644
--- a/libs/ui/KeyCharacterMap.cpp
+++ b/libs/ui/KeyCharacterMap.cpp
@@ -141,9 +141,8 @@
char16_t KeyCharacterMap::getDisplayLabel(int32_t keyCode) const {
char16_t result = 0;
- ssize_t index = mKeys.indexOfKey(keyCode);
- if (index >= 0) {
- const Key* key = mKeys.valueAt(index);
+ const Key* key;
+ if (getKey(keyCode, &key)) {
result = key->label;
}
#if DEBUG_MAPPING
@@ -154,9 +153,8 @@
char16_t KeyCharacterMap::getNumber(int32_t keyCode) const {
char16_t result = 0;
- ssize_t index = mKeys.indexOfKey(keyCode);
- if (index >= 0) {
- const Key* key = mKeys.valueAt(index);
+ const Key* key;
+ if (getKey(keyCode, &key)) {
result = key->number;
}
#if DEBUG_MAPPING
@@ -167,15 +165,10 @@
char16_t KeyCharacterMap::getCharacter(int32_t keyCode, int32_t metaState) const {
char16_t result = 0;
- ssize_t index = mKeys.indexOfKey(keyCode);
- if (index >= 0) {
- const Key* key = mKeys.valueAt(index);
- for (const Behavior* behavior = key->firstBehavior; behavior; behavior = behavior->next) {
- if ((behavior->metaState & metaState) == behavior->metaState) {
- result = behavior->character;
- break;
- }
- }
+ const Key* key;
+ const Behavior* behavior;
+ if (getKeyBehavior(keyCode, metaState, &key, &behavior)) {
+ result = behavior->character;
}
#if DEBUG_MAPPING
LOGD("getCharacter: keyCode=%d, metaState=0x%08x ~ Result %d.", keyCode, metaState, result);
@@ -183,13 +176,33 @@
return result;
}
+bool KeyCharacterMap::getFallbackAction(int32_t keyCode, int32_t metaState,
+ FallbackAction* outFallbackAction) const {
+ outFallbackAction->keyCode = 0;
+ outFallbackAction->metaState = 0;
+
+ bool result = false;
+ const Key* key;
+ const Behavior* behavior;
+ if (getKeyBehavior(keyCode, metaState, &key, &behavior)) {
+ outFallbackAction->keyCode = behavior->fallbackKeyCode;
+ outFallbackAction->metaState = metaState & ~behavior->metaState;
+ result = true;
+ }
+#if DEBUG_MAPPING
+ LOGD("getFallbackKeyCode: keyCode=%d, metaState=0x%08x ~ Result %s, "
+ "fallback keyCode=%d, fallback metaState=0x%08x.",
+ keyCode, metaState, result ? "true" : "false",
+ outFallbackAction->keyCode, outFallbackAction->metaState);
+#endif
+ return result;
+}
+
char16_t KeyCharacterMap::getMatch(int32_t keyCode, const char16_t* chars, size_t numChars,
int32_t metaState) const {
char16_t result = 0;
- ssize_t index = mKeys.indexOfKey(keyCode);
- if (index >= 0) {
- const Key* key = mKeys.valueAt(index);
-
+ const Key* key;
+ if (getKey(keyCode, &key)) {
// Try to find the most general behavior that maps to this character.
// For example, the base key behavior will usually be last in the list.
// However, if we find a perfect meta state match for one behavior then use that one.
@@ -238,7 +251,7 @@
}
#if DEBUG_MAPPING
LOGD("getEvents: deviceId=%d, chars=[%s] ~ Generated %d events.",
- deviceId, toString(chars, numChars).string(), outEvents.size());
+ deviceId, toString(chars, numChars).string(), int32_t(outEvents.size()));
for (size_t i = 0; i < outEvents.size(); i++) {
LOGD(" Key: keyCode=%d, metaState=0x%08x, %s.",
outEvents[i].getKeyCode(), outEvents[i].getMetaState(),
@@ -248,6 +261,32 @@
return true;
}
+bool KeyCharacterMap::getKey(int32_t keyCode, const Key** outKey) const {
+ ssize_t index = mKeys.indexOfKey(keyCode);
+ if (index >= 0) {
+ *outKey = mKeys.valueAt(index);
+ return true;
+ }
+ return false;
+}
+
+bool KeyCharacterMap::getKeyBehavior(int32_t keyCode, int32_t metaState,
+ const Key** outKey, const Behavior** outBehavior) const {
+ const Key* key;
+ if (getKey(keyCode, &key)) {
+ const Behavior* behavior = key->firstBehavior;
+ while (behavior) {
+ if ((behavior->metaState & metaState) == behavior->metaState) {
+ *outKey = key;
+ *outBehavior = behavior;
+ return true;
+ }
+ behavior = behavior->next;
+ }
+ }
+ return false;
+}
+
bool KeyCharacterMap::findKey(char16_t ch, int32_t* outKeyCode, int32_t* outMetaState) const {
if (!ch) {
return false;
diff --git a/libs/ui/tests/InputDispatcher_test.cpp b/libs/ui/tests/InputDispatcher_test.cpp
index 68f9037..7e17c57 100644
--- a/libs/ui/tests/InputDispatcher_test.cpp
+++ b/libs/ui/tests/InputDispatcher_test.cpp
@@ -66,7 +66,7 @@
}
virtual bool dispatchUnhandledKey(const sp<InputChannel>& inputChannel,
- const KeyEvent* keyEvent, uint32_t policyFlags) {
+ const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
return false;
}
diff --git a/libs/ui/tests/InputPublisherAndConsumer_test.cpp b/libs/ui/tests/InputPublisherAndConsumer_test.cpp
index c6eac25..903fcaf 100644
--- a/libs/ui/tests/InputPublisherAndConsumer_test.cpp
+++ b/libs/ui/tests/InputPublisherAndConsumer_test.cpp
@@ -123,7 +123,7 @@
<< "consumer sendFinishedSignal should return OK";
bool handled = false;
- status = mPublisher->receiveFinishedSignal(handled);
+ status = mPublisher->receiveFinishedSignal(&handled);
ASSERT_EQ(OK, status)
<< "publisher receiveFinishedSignal should return OK";
ASSERT_TRUE(handled)
@@ -287,7 +287,7 @@
<< "consumer sendFinishedSignal should return OK";
bool handled = true;
- status = mPublisher->receiveFinishedSignal(handled);
+ status = mPublisher->receiveFinishedSignal(&handled);
ASSERT_EQ(OK, status)
<< "publisher receiveFinishedSignal should return OK";
ASSERT_FALSE(handled)
diff --git a/libs/ui/tests/InputReader_test.cpp b/libs/ui/tests/InputReader_test.cpp
index d6c2cbd..97cbc25 100644
--- a/libs/ui/tests/InputReader_test.cpp
+++ b/libs/ui/tests/InputReader_test.cpp
@@ -1137,6 +1137,7 @@
mFakeDispatcher = new FakeInputDispatcher();
mFakeContext = new FakeInputReaderContext(mFakeEventHub, mFakePolicy, mFakeDispatcher);
+ mFakeEventHub->addDevice(DEVICE_ID, String8(DEVICE_NAME), 0);
mDevice = new InputDevice(mFakeContext, DEVICE_ID, String8(DEVICE_NAME));
}
@@ -1753,7 +1754,7 @@
process(mapper, ARBITRARY_TIME, DEVICE_ID,
EV_KEY, KEY_CAPSLOCK, AKEYCODE_CAPS_LOCK, 1, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID,
- EV_KEY, KEY_CAPSLOCK, AKEYCODE_CAPS_LOCK, 1, 0);
+ EV_KEY, KEY_CAPSLOCK, AKEYCODE_CAPS_LOCK, 0, 0);
ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
@@ -2225,19 +2226,19 @@
}
-TEST_F(SingleTouchInputMapperTest, GetSources_WhenDisplayTypeIsTouchPad_ReturnsTouchPad) {
+TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsTouchPad_ReturnsTouchPad) {
SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
prepareAxes(POSITION);
- addConfigurationProperty("touch.displayType", "touchPad");
+ addConfigurationProperty("touch.deviceType", "touchPad");
addMapperAndConfigure(mapper);
ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, mapper->getSources());
}
-TEST_F(SingleTouchInputMapperTest, GetSources_WhenDisplayTypeIsTouchScreen_ReturnsTouchScreen) {
+TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsTouchScreen_ReturnsTouchScreen) {
SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
prepareAxes(POSITION);
- addConfigurationProperty("touch.displayType", "touchScreen");
+ addConfigurationProperty("touch.deviceType", "touchScreen");
addMapperAndConfigure(mapper);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper->getSources());
diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
index d3a71b3..d539833 100755
--- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
+++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
@@ -28,6 +28,8 @@
import android.os.RemoteException;
import android.util.Log;
+import com.android.internal.R;
+
/**
* A GPS Network-initiated Handler class used by LocationManager.
*
@@ -182,8 +184,8 @@
return;
}
- String title = getNotifTitle(notif);
- String message = getNotifMessage(notif);
+ String title = getNotifTitle(notif, mContext);
+ String message = getNotifMessage(notif, mContext);
if (DEBUG) Log.d(TAG, "setNiNotification, notifyId: " + notif.notificationId +
", title: " + title +
@@ -203,7 +205,7 @@
}
mNiNotification.flags = Notification.FLAG_ONGOING_EVENT;
- mNiNotification.tickerText = getNotifTicker(notif);
+ mNiNotification.tickerText = getNotifTicker(notif, mContext);
// if not to popup dialog immediately, pending intent will open the dialog
Intent intent = !mPopupImmediately ? getDlgIntent(notif) : new Intent();
@@ -234,8 +236,8 @@
private Intent getDlgIntent(GpsNiNotification notif)
{
Intent intent = new Intent();
- String title = getDialogTitle(notif);
- String message = getDialogMessage(notif);
+ String title = getDialogTitle(notif, mContext);
+ String message = getDialogMessage(notif, mContext);
// directly bring up the NI activity
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@@ -412,41 +414,40 @@
}
// change this to configure notification display
- static private String getNotifTicker(GpsNiNotification notif)
+ static private String getNotifTicker(GpsNiNotification notif, Context context)
{
- String ticker = String.format("Position request! ReqId: [%s] ClientName: [%s]",
+ String ticker = String.format(context.getString(R.string.gpsNotifTicker),
decodeString(notif.requestorId, mIsHexInput, notif.requestorIdEncoding),
decodeString(notif.text, mIsHexInput, notif.textEncoding));
return ticker;
}
// change this to configure notification display
- static private String getNotifTitle(GpsNiNotification notif)
+ static private String getNotifTitle(GpsNiNotification notif, Context context)
{
- String title = String.format("Position Request");
+ String title = String.format(context.getString(R.string.gpsNotifTitle));
return title;
}
// change this to configure notification display
- static private String getNotifMessage(GpsNiNotification notif)
+ static private String getNotifMessage(GpsNiNotification notif, Context context)
{
- String message = String.format(
- "NI Request received from [%s] for client [%s]!",
+ String message = String.format(context.getString(R.string.gpsNotifMessage),
decodeString(notif.requestorId, mIsHexInput, notif.requestorIdEncoding),
decodeString(notif.text, mIsHexInput, notif.textEncoding));
return message;
}
// change this to configure dialog display (for verification)
- static public String getDialogTitle(GpsNiNotification notif)
+ static public String getDialogTitle(GpsNiNotification notif, Context context)
{
- return getNotifTitle(notif);
+ return getNotifTitle(notif, context);
}
// change this to configure dialog display (for verification)
- static private String getDialogMessage(GpsNiNotification notif)
+ static private String getDialogMessage(GpsNiNotification notif, Context context)
{
- return getNotifMessage(notif);
+ return getNotifMessage(notif, context);
}
}
diff --git a/media/java/android/media/MtpDatabase.java b/media/java/android/media/MtpDatabase.java
index 139a6ea..6056a0f 100644
--- a/media/java/android/media/MtpDatabase.java
+++ b/media/java/android/media/MtpDatabase.java
@@ -31,6 +31,8 @@
import android.provider.MediaStore.Images;
import android.provider.MediaStore.MediaColumns;
import android.util.Log;
+import android.view.Display;
+import android.view.WindowManager;
import java.io.File;
import java.util.HashMap;
@@ -460,6 +462,7 @@
return new int[] {
MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER,
MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME,
+ MtpConstants.DEVICE_PROPERTY_IMAGE_SIZE,
};
}
@@ -592,9 +595,21 @@
c.close();
}
}
- }
- return MtpConstants.RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
+ case MtpConstants.DEVICE_PROPERTY_IMAGE_SIZE:
+ // use screen size as max image size
+ Display display = ((WindowManager)mContext.getSystemService(
+ Context.WINDOW_SERVICE)).getDefaultDisplay();
+ int width = display.getWidth();
+ int height = display.getHeight();
+ String imageSize = Integer.toString(width) + "x" + Integer.toString(height);
+ imageSize.getChars(0, imageSize.length(), outStringValue, 0);
+ outStringValue[imageSize.length()] = 0;
+ return MtpConstants.RESPONSE_OK;
+
+ default:
+ return MtpConstants.RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
+ }
}
private int setDeviceProperty(int property, long intValue, String stringValue) {
diff --git a/media/jni/android_media_MtpDatabase.cpp b/media/jni/android_media_MtpDatabase.cpp
index 1909e6a..9bb93fd 100644
--- a/media/jni/android_media_MtpDatabase.cpp
+++ b/media/jni/android_media_MtpDatabase.cpp
@@ -860,8 +860,9 @@
};
static const PropertyTableEntry kDevicePropertyTable[] = {
- { MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER, MTP_TYPE_STR },
- { MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME, MTP_TYPE_STR },
+ { MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER, MTP_TYPE_STR },
+ { MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME, MTP_TYPE_STR },
+ { MTP_DEVICE_PROPERTY_IMAGE_SIZE, MTP_TYPE_STR },
};
bool MyMtpDatabase::getObjectPropertyInfo(MtpObjectProperty property, int& type) {
@@ -932,6 +933,9 @@
MtpProperty* result = NULL;
switch (property) {
case MTP_PROPERTY_OBJECT_FORMAT:
+ // use format as default value
+ result = new MtpProperty(property, MTP_TYPE_UINT16, false, format);
+ break;
case MTP_PROPERTY_PROTECTION_STATUS:
case MTP_PROPERTY_TRACK:
result = new MtpProperty(property, MTP_TYPE_UINT16);
@@ -973,31 +977,35 @@
}
MtpProperty* MyMtpDatabase::getDevicePropertyDesc(MtpDeviceProperty property) {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
MtpProperty* result = NULL;
+ bool writable = false;
+
switch (property) {
case MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER:
case MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME:
- {
- // writeable string properties
- result = new MtpProperty(property, MTP_TYPE_STR, true);
+ writable = true;
+ // fall through
+ case MTP_DEVICE_PROPERTY_IMAGE_SIZE:
+ result = new MtpProperty(property, MTP_TYPE_STR, writable);
- // set current value
- JNIEnv* env = AndroidRuntime::getJNIEnv();
+ // get current value
jint ret = env->CallIntMethod(mDatabase, method_getDeviceProperty,
(jint)property, mLongBuffer, mStringBuffer);
if (ret == MTP_RESPONSE_OK) {
jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
result->setCurrentValue(str);
+ // for read-only properties it is safe to assume current value is default value
+ if (!writable)
+ result->setDefaultValue(str);
env->ReleaseCharArrayElements(mStringBuffer, str, 0);
} else {
LOGE("unable to read device property, response: %04X", ret);
}
-
- checkAndClearExceptionFromCallback(env, __FUNCTION__);
break;
- }
}
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
return result;
}
diff --git a/media/mtp/Android.mk b/media/mtp/Android.mk
index b7e1a2a..e285847 100644
--- a/media/mtp/Android.mk
+++ b/media/mtp/Android.mk
@@ -47,3 +47,32 @@
endif
+ifeq ($(HOST_OS),linux)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ MtpClient.cpp \
+ MtpDataPacket.cpp \
+ MtpDebug.cpp \
+ MtpDevice.cpp \
+ MtpEventPacket.cpp \
+ MtpDeviceInfo.cpp \
+ MtpObjectInfo.cpp \
+ MtpPacket.cpp \
+ MtpProperty.cpp \
+ MtpRequestPacket.cpp \
+ MtpResponsePacket.cpp \
+ MtpStorageInfo.cpp \
+ MtpStringBuffer.cpp \
+ MtpStorage.cpp \
+ MtpUtils.cpp \
+ PtpCursor.cpp \
+
+LOCAL_MODULE:= libmtp
+
+LOCAL_CFLAGS := -DMTP_HOST
+
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+endif
diff --git a/media/mtp/MtpDevice.cpp b/media/mtp/MtpDevice.cpp
index 416ebfe..8ad39dc 100644
--- a/media/mtp/MtpDevice.cpp
+++ b/media/mtp/MtpDevice.cpp
@@ -63,17 +63,13 @@
openSession();
mDeviceInfo = getDeviceInfo();
if (mDeviceInfo) {
- mDeviceInfo->print();
-
if (mDeviceInfo->mDeviceProperties) {
int count = mDeviceInfo->mDeviceProperties->size();
for (int i = 0; i < count; i++) {
MtpDeviceProperty propCode = (*mDeviceInfo->mDeviceProperties)[i];
MtpProperty* property = getDevicePropDesc(propCode);
- if (property) {
- property->print();
+ if (property)
mDeviceProperties.push(property);
- }
}
}
}
@@ -87,6 +83,45 @@
}
}
+void MtpDevice::print() {
+ if (mDeviceInfo) {
+ mDeviceInfo->print();
+
+ if (mDeviceInfo->mDeviceProperties) {
+ LOGI("***** DEVICE PROPERTIES *****\n");
+ int count = mDeviceInfo->mDeviceProperties->size();
+ for (int i = 0; i < count; i++) {
+ MtpDeviceProperty propCode = (*mDeviceInfo->mDeviceProperties)[i];
+ MtpProperty* property = getDevicePropDesc(propCode);
+ if (property) {
+ property->print();
+ }
+ }
+ }
+ }
+
+ if (mDeviceInfo->mPlaybackFormats) {
+ LOGI("***** OBJECT PROPERTIES *****\n");
+ int count = mDeviceInfo->mPlaybackFormats->size();
+ for (int i = 0; i < count; i++) {
+ MtpObjectFormat format = (*mDeviceInfo->mPlaybackFormats)[i];
+ LOGI("*** FORMAT: %s\n", MtpDebug::getFormatCodeName(format));
+ MtpObjectPropertyList* props = getObjectPropsSupported(format);
+ if (props) {
+ for (int j = 0; j < props->size(); j++) {
+ MtpObjectProperty prop = (*props)[j];
+ MtpProperty* property = getObjectPropDesc(prop, format);
+ if (property)
+ property->print();
+ else
+ LOGE("could not fetch property: %s",
+ MtpDebug::getObjectPropCodeName(prop));
+ }
+ }
+ }
+ }
+}
+
const char* MtpDevice::getDeviceName() {
if (mDevice)
return usb_device_get_name(mDevice);
@@ -330,6 +365,23 @@
return -1;
}
+MtpObjectPropertyList* MtpDevice::getObjectPropsSupported(MtpObjectFormat format) {
+ Mutex::Autolock autoLock(mMutex);
+
+ mRequest.reset();
+ mRequest.setParameter(1, format);
+ if (!sendRequest(MTP_OPERATION_GET_OBJECT_PROPS_SUPPORTED))
+ return NULL;
+ if (!readData())
+ return NULL;
+ MtpResponseCode ret = readResponse();
+ if (ret == MTP_RESPONSE_OK) {
+ return mData.getAUInt16();
+ }
+ return NULL;
+
+}
+
MtpProperty* MtpDevice::getDevicePropDesc(MtpDeviceProperty code) {
Mutex::Autolock autoLock(mMutex);
@@ -348,6 +400,25 @@
return NULL;
}
+MtpProperty* MtpDevice::getObjectPropDesc(MtpObjectProperty code, MtpObjectFormat format) {
+ Mutex::Autolock autoLock(mMutex);
+
+ mRequest.reset();
+ mRequest.setParameter(1, code);
+ mRequest.setParameter(2, format);
+ if (!sendRequest(MTP_OPERATION_GET_OBJECT_PROP_DESC))
+ return NULL;
+ if (!readData())
+ return NULL;
+ MtpResponseCode ret = readResponse();
+ if (ret == MTP_RESPONSE_OK) {
+ MtpProperty* property = new MtpProperty;
+ property->read(mData);
+ return property;
+ }
+ return NULL;
+}
+
// reads the object's data and writes it to the specified file path
bool MtpDevice::readObject(MtpObjectHandle handle, const char* destPath, int group, int perm) {
LOGD("readObject: %s", destPath);
diff --git a/media/mtp/MtpDevice.h b/media/mtp/MtpDevice.h
index 21c85d5..6ffbd24 100644
--- a/media/mtp/MtpDevice.h
+++ b/media/mtp/MtpDevice.h
@@ -67,6 +67,7 @@
void initialize();
void close();
+ void print();
const char* getDeviceName();
bool openSession();
@@ -85,7 +86,10 @@
MtpObjectHandle getParent(MtpObjectHandle handle);
MtpObjectHandle getStorageID(MtpObjectHandle handle);
+ MtpObjectPropertyList* getObjectPropsSupported(MtpObjectFormat format);
+
MtpProperty* getDevicePropDesc(MtpDeviceProperty code);
+ MtpProperty* getObjectPropDesc(MtpObjectProperty code, MtpObjectFormat format);
bool readObject(MtpObjectHandle handle, const char* destPath, int group,
int perm);
diff --git a/media/mtp/MtpProperty.cpp b/media/mtp/MtpProperty.cpp
index 4356a6f..b095ce1 100644
--- a/media/mtp/MtpProperty.cpp
+++ b/media/mtp/MtpProperty.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "MtpProperty"
#include "MtpDataPacket.h"
+#include "MtpDebug.h"
#include "MtpProperty.h"
#include "MtpStringBuffer.h"
#include "MtpUtils.h"
@@ -121,9 +122,8 @@
}
void MtpProperty::read(MtpDataPacket& packet) {
- bool deviceProp = isDeviceProperty();
-
mCode = packet.getUInt16();
+ bool deviceProp = isDeviceProperty();
mType = packet.getUInt16();
mWriteable = (packet.getUInt8() == 1);
switch (mType) {
@@ -317,9 +317,93 @@
}
void MtpProperty::print() {
- LOGV("MtpProperty %04X\n", mCode);
- LOGV(" type %04X\n", mType);
- LOGV(" writeable %s\n", (mWriteable ? "true" : "false"));
+ MtpString buffer;
+ bool deviceProp = isDeviceProperty();
+ if (deviceProp)
+ LOGI(" %s (%04X)", MtpDebug::getDevicePropCodeName(mCode), mCode);
+ else
+ LOGI(" %s (%04X)", MtpDebug::getObjectPropCodeName(mCode), mCode);
+ LOGI(" type %04X", mType);
+ LOGI(" writeable %s", (mWriteable ? "true" : "false"));
+ buffer = " default value: ";
+ print(mDefaultValue, buffer);
+ LOGI("%s", (const char *)buffer);
+ if (deviceProp) {
+ buffer = " current value: ";
+ print(mCurrentValue, buffer);
+ LOGI("%s", (const char *)buffer);
+ }
+ switch (mFormFlag) {
+ case kFormNone:
+ break;
+ case kFormRange:
+ buffer = " Range (";
+ print(mMinimumValue, buffer);
+ buffer += ", ";
+ print(mMaximumValue, buffer);
+ buffer += ", ";
+ print(mStepSize, buffer);
+ LOGI("%s", (const char *)buffer);
+ break;
+ case kFormEnum:
+ buffer = " Enum { ";
+ for (int i = 0; i < mEnumLength; i++) {
+ print(mEnumValues[i], buffer);
+ buffer += " ";
+ }
+ buffer += "}";
+ LOGI("%s", (const char *)buffer);
+ break;
+ case kFormDateTime:
+ LOGI(" DateTime\n");
+ break;
+ default:
+ LOGI(" form %d\n", mFormFlag);
+ break;
+ }
+}
+
+void MtpProperty::print(MtpPropertyValue& value, MtpString& buffer) {
+ switch (mType) {
+ case MTP_TYPE_INT8:
+ buffer.appendFormat("%d", value.u.i8);
+ break;
+ case MTP_TYPE_UINT8:
+ buffer.appendFormat("%d", value.u.u8);
+ break;
+ case MTP_TYPE_INT16:
+ buffer.appendFormat("%d", value.u.i16);
+ break;
+ case MTP_TYPE_UINT16:
+ buffer.appendFormat("%d", value.u.u16);
+ break;
+ case MTP_TYPE_INT32:
+ buffer.appendFormat("%d", value.u.i32);
+ break;
+ case MTP_TYPE_UINT32:
+ buffer.appendFormat("%d", value.u.u32);
+ break;
+ case MTP_TYPE_INT64:
+ buffer.appendFormat("%lld", value.u.i64);
+ break;
+ case MTP_TYPE_UINT64:
+ buffer.appendFormat("%lld", value.u.u64);
+ break;
+ case MTP_TYPE_INT128:
+ buffer.appendFormat("%08X%08X%08X%08X", value.u.i128[0], value.u.i128[1],
+ value.u.i128[2], value.u.i128[3]);
+ break;
+ case MTP_TYPE_UINT128:
+ buffer.appendFormat("%08X%08X%08X%08X", value.u.u128[0], value.u.u128[1],
+ value.u.u128[2], value.u.u128[3]);
+ break;
+ case MTP_TYPE_STR:
+ buffer.appendFormat("%s", value.str);
+ break;
+ default:
+ LOGE("unsupported type for MtpProperty::print\n");
+ break;
+ }
}
void MtpProperty::readValue(MtpDataPacket& packet, MtpPropertyValue& value) {
diff --git a/media/mtp/MtpProperty.h b/media/mtp/MtpProperty.h
index f783a87..06ca56e 100644
--- a/media/mtp/MtpProperty.h
+++ b/media/mtp/MtpProperty.h
@@ -94,6 +94,7 @@
void setFormDateTime();
void print();
+ void print(MtpPropertyValue& value, MtpString& buffer);
inline bool isDeviceProperty() const {
return ( ((mCode & 0xF000) == 0x5000)
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index de6cbac..5c1e02a 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -423,7 +423,7 @@
if (!mSessionOpen)
return MTP_RESPONSE_SESSION_NOT_OPEN;
MtpObjectFormat format = mRequest.getParameter(1);
- MtpDevicePropertyList* properties = mDatabase->getSupportedObjectProperties(format);
+ MtpObjectPropertyList* properties = mDatabase->getSupportedObjectProperties(format);
mData.putAUInt16(properties);
delete properties;
return MTP_RESPONSE_OK;
diff --git a/native/include/android/input.h b/native/include/android/input.h
index 861ec8b..e196686 100644
--- a/native/include/android/input.h
+++ b/native/include/android/input.h
@@ -215,7 +215,15 @@
* tracked from its initial down. That is, somebody requested that tracking
* started on the key down and a long press has not caused
* the tracking to be canceled. */
- AKEY_EVENT_FLAG_TRACKING = 0x200
+ AKEY_EVENT_FLAG_TRACKING = 0x200,
+
+ /* Set when a key event has been synthesized to implement default behavior
+ * for an event that the application did not handle.
+ * Fallback key events are generated by unhandled trackball motions
+ * (to emulate a directional keypad) and by certain unhandled key presses
+ * that are declared in the key map (such as special function numeric keypad
+ * keys when numlock is off). */
+ AKEY_EVENT_FLAG_FALLBACK = 0x400,
};
/*
diff --git a/native/include/android/keycodes.h b/native/include/android/keycodes.h
index 5f33ad5..b026a0c 100644
--- a/native/include/android/keycodes.h
+++ b/native/include/android/keycodes.h
@@ -230,6 +230,7 @@
AKEYCODE_PROG_GREEN = 184,
AKEYCODE_PROG_YELLOW = 185,
AKEYCODE_PROG_BLUE = 186,
+ AKEYCODE_APP_SWITCH = 187,
// NOTE: If you add a new keycode here you must also add it to several other files.
// Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
diff --git a/opengl/java/android/opengl/ETC1.java b/opengl/java/android/opengl/ETC1.java
index f3dac77..fb5f9b4 100644
--- a/opengl/java/android/opengl/ETC1.java
+++ b/opengl/java/android/opengl/ETC1.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2009 Google Inc.
+ * Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
diff --git a/opengl/java/android/opengl/ETC1Util.java b/opengl/java/android/opengl/ETC1Util.java
index dd28d1d..3629d41 100644
--- a/opengl/java/android/opengl/ETC1Util.java
+++ b/opengl/java/android/opengl/ETC1Util.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2009 Google Inc.
+ * Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
diff --git a/opengl/java/android/opengl/GLES10.java b/opengl/java/android/opengl/GLES10.java
index 790acbd..7c0f949 100644
--- a/opengl/java/android/opengl/GLES10.java
+++ b/opengl/java/android/opengl/GLES10.java
@@ -1,19 +1,18 @@
/*
-**
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
// This source file is automatically generated
diff --git a/opengl/java/android/opengl/GLES10Ext.java b/opengl/java/android/opengl/GLES10Ext.java
index 81fc59e..116ab9d 100644
--- a/opengl/java/android/opengl/GLES10Ext.java
+++ b/opengl/java/android/opengl/GLES10Ext.java
@@ -1,19 +1,18 @@
/*
-**
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
// This source file is automatically generated
diff --git a/opengl/java/android/opengl/GLES11.java b/opengl/java/android/opengl/GLES11.java
index 1ca179b..b24c043 100644
--- a/opengl/java/android/opengl/GLES11.java
+++ b/opengl/java/android/opengl/GLES11.java
@@ -1,19 +1,18 @@
/*
-**
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
// This source file is automatically generated
diff --git a/opengl/java/android/opengl/GLES11Ext.java b/opengl/java/android/opengl/GLES11Ext.java
index 25d5467..a9a7a22 100644
--- a/opengl/java/android/opengl/GLES11Ext.java
+++ b/opengl/java/android/opengl/GLES11Ext.java
@@ -1,19 +1,18 @@
/*
-**
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
// This source file is automatically generated
diff --git a/opengl/java/android/opengl/GLES20.java b/opengl/java/android/opengl/GLES20.java
index 635f811..700164b 100644
--- a/opengl/java/android/opengl/GLES20.java
+++ b/opengl/java/android/opengl/GLES20.java
@@ -1,19 +1,18 @@
/*
-**
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
// This source file is automatically generated
diff --git a/opengl/java/com/google/android/gles_jni/EGLConfigImpl.java b/opengl/java/com/google/android/gles_jni/EGLConfigImpl.java
index b03392e..c2f4400 100644
--- a/opengl/java/com/google/android/gles_jni/EGLConfigImpl.java
+++ b/opengl/java/com/google/android/gles_jni/EGLConfigImpl.java
@@ -1,19 +1,18 @@
-/*
-**
-** Copyright 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.
-*/
+/*
+ * 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.
+ */
package com.google.android.gles_jni;
diff --git a/opengl/java/com/google/android/gles_jni/EGLContextImpl.java b/opengl/java/com/google/android/gles_jni/EGLContextImpl.java
index f10c02f..9cf5de7 100644
--- a/opengl/java/com/google/android/gles_jni/EGLContextImpl.java
+++ b/opengl/java/com/google/android/gles_jni/EGLContextImpl.java
@@ -1,19 +1,18 @@
-/*
-**
-** Copyright 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.
-*/
+/*
+ * 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.
+ */
package com.google.android.gles_jni;
diff --git a/opengl/java/com/google/android/gles_jni/EGLDisplayImpl.java b/opengl/java/com/google/android/gles_jni/EGLDisplayImpl.java
index 6321632..cb94888 100644
--- a/opengl/java/com/google/android/gles_jni/EGLDisplayImpl.java
+++ b/opengl/java/com/google/android/gles_jni/EGLDisplayImpl.java
@@ -1,19 +1,18 @@
-/*
-**
-** Copyright 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.
-*/
+/*
+ * 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.
+ */
package com.google.android.gles_jni;
diff --git a/opengl/java/com/google/android/gles_jni/EGLImpl.java b/opengl/java/com/google/android/gles_jni/EGLImpl.java
index 3e06ded..8a7124d 100644
--- a/opengl/java/com/google/android/gles_jni/EGLImpl.java
+++ b/opengl/java/com/google/android/gles_jni/EGLImpl.java
@@ -1,19 +1,18 @@
/*
-**
-** Copyright 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.
-*/
+ * 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.
+ */
package com.google.android.gles_jni;
diff --git a/opengl/java/com/google/android/gles_jni/EGLSurfaceImpl.java b/opengl/java/com/google/android/gles_jni/EGLSurfaceImpl.java
index 66cc200..f6b90ab 100644
--- a/opengl/java/com/google/android/gles_jni/EGLSurfaceImpl.java
+++ b/opengl/java/com/google/android/gles_jni/EGLSurfaceImpl.java
@@ -1,19 +1,18 @@
-/*
-**
-** Copyright 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.
-*/
+/*
+ * 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.
+ */
package com.google.android.gles_jni;
diff --git a/opengl/java/com/google/android/gles_jni/GLImpl.java b/opengl/java/com/google/android/gles_jni/GLImpl.java
index 090c0cb7..50f6760 100644
--- a/opengl/java/com/google/android/gles_jni/GLImpl.java
+++ b/opengl/java/com/google/android/gles_jni/GLImpl.java
@@ -1,19 +1,18 @@
-/* //device/java/android/com/google/android/gles_jni/GLImpl.java
-**
-** Copyright 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.
-*/
+/*
+ * 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.
+ */
// This source file is automatically generated
diff --git a/opengl/java/javax/microedition/khronos/egl/EGL.java b/opengl/java/javax/microedition/khronos/egl/EGL.java
index b743968..18f8ae6 100644
--- a/opengl/java/javax/microedition/khronos/egl/EGL.java
+++ b/opengl/java/javax/microedition/khronos/egl/EGL.java
@@ -1,19 +1,18 @@
-/*
-**
-** Copyright 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.
-*/
+/*
+ * 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.
+ */
package javax.microedition.khronos.egl;
diff --git a/opengl/java/javax/microedition/khronos/egl/EGLConfig.java b/opengl/java/javax/microedition/khronos/egl/EGLConfig.java
index a1e496c..c8a9ba2 100644
--- a/opengl/java/javax/microedition/khronos/egl/EGLConfig.java
+++ b/opengl/java/javax/microedition/khronos/egl/EGLConfig.java
@@ -1,19 +1,18 @@
-/*
-**
-** Copyright 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.
-*/
+/*
+ * 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.
+ */
package javax.microedition.khronos.egl;
diff --git a/opengl/java/javax/microedition/khronos/egl/EGLContext.java b/opengl/java/javax/microedition/khronos/egl/EGLContext.java
index fc94492..f8d745d 100644
--- a/opengl/java/javax/microedition/khronos/egl/EGLContext.java
+++ b/opengl/java/javax/microedition/khronos/egl/EGLContext.java
@@ -1,19 +1,18 @@
-/*
-**
-** Copyright 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.
-*/
+/*
+ * 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.
+ */
package javax.microedition.khronos.egl;
diff --git a/opengl/java/javax/microedition/khronos/egl/EGLDisplay.java b/opengl/java/javax/microedition/khronos/egl/EGLDisplay.java
index cd8a755..5368b4b 100644
--- a/opengl/java/javax/microedition/khronos/egl/EGLDisplay.java
+++ b/opengl/java/javax/microedition/khronos/egl/EGLDisplay.java
@@ -1,19 +1,18 @@
-/*
-**
-** Copyright 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.
-*/
+/*
+ * 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.
+ */
package javax.microedition.khronos.egl;
diff --git a/opengl/java/javax/microedition/khronos/egl/EGLSurface.java b/opengl/java/javax/microedition/khronos/egl/EGLSurface.java
index 5349bc1..e1d08d3 100644
--- a/opengl/java/javax/microedition/khronos/egl/EGLSurface.java
+++ b/opengl/java/javax/microedition/khronos/egl/EGLSurface.java
@@ -1,19 +1,18 @@
-/*
-**
-** Copyright 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.
-*/
+/*
+ * 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.
+ */
package javax.microedition.khronos.egl;
diff --git a/opengl/java/javax/microedition/khronos/opengles/GL.java b/opengl/java/javax/microedition/khronos/opengles/GL.java
index 3b78f3d..d5b60c6 100644
--- a/opengl/java/javax/microedition/khronos/opengles/GL.java
+++ b/opengl/java/javax/microedition/khronos/opengles/GL.java
@@ -1,19 +1,18 @@
-/* //device/java/android/javax/microedition/khronos/opengles/GL.java
-**
-** Copyright 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.
-*/
+/*
+ * 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.
+ */
package javax.microedition.khronos.opengles;
diff --git a/opengl/java/javax/microedition/khronos/opengles/GL10.java b/opengl/java/javax/microedition/khronos/opengles/GL10.java
index 4fcfb52..f48ecde 100644
--- a/opengl/java/javax/microedition/khronos/opengles/GL10.java
+++ b/opengl/java/javax/microedition/khronos/opengles/GL10.java
@@ -1,19 +1,18 @@
-/* //device/java/android/javax/microedition/khronos/opengles/GL10.java
-**
-** Copyright 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.
-*/
+/*
+ * 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.
+ */
// This source file is automatically generated
diff --git a/opengl/java/javax/microedition/khronos/opengles/GL10Ext.java b/opengl/java/javax/microedition/khronos/opengles/GL10Ext.java
index 562b20a..f3252ab 100644
--- a/opengl/java/javax/microedition/khronos/opengles/GL10Ext.java
+++ b/opengl/java/javax/microedition/khronos/opengles/GL10Ext.java
@@ -1,19 +1,18 @@
-/* //device/java/android/javax/microedition/khronos/opengles/GL10Ext.java
-**
-** Copyright 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.
-*/
+/*
+ * 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.
+ */
// This source file is automatically generated
diff --git a/opengl/java/javax/microedition/khronos/opengles/GL11.java b/opengl/java/javax/microedition/khronos/opengles/GL11.java
index 3ba110c..943a5be 100644
--- a/opengl/java/javax/microedition/khronos/opengles/GL11.java
+++ b/opengl/java/javax/microedition/khronos/opengles/GL11.java
@@ -1,19 +1,18 @@
-/* //device/java/android/javax/microedition/khronos/opengles/GL11.java
-**
-** Copyright 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.
-*/
+/*
+ * 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.
+ */
// This source file is automatically generated
diff --git a/opengl/java/javax/microedition/khronos/opengles/GL11Ext.java b/opengl/java/javax/microedition/khronos/opengles/GL11Ext.java
index 459a1ab..842db7a 100644
--- a/opengl/java/javax/microedition/khronos/opengles/GL11Ext.java
+++ b/opengl/java/javax/microedition/khronos/opengles/GL11Ext.java
@@ -1,19 +1,18 @@
-/* //device/java/android/javax/microedition/khronos/opengles/GL11Ext.java
-**
-** Copyright 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.
-*/
+/*
+ * 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.
+ */
// This source file is automatically generated
diff --git a/opengl/java/javax/microedition/khronos/opengles/GL11ExtensionPack.java b/opengl/java/javax/microedition/khronos/opengles/GL11ExtensionPack.java
index 933c91e..97d5fd8 100644
--- a/opengl/java/javax/microedition/khronos/opengles/GL11ExtensionPack.java
+++ b/opengl/java/javax/microedition/khronos/opengles/GL11ExtensionPack.java
@@ -1,19 +1,18 @@
-/* //device/java/android/javax/microedition/khronos/opengles/GL11ExtensionPack.java
-**
-** Copyright 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.
-*/
+/*
+ * 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.
+ */
// This source file is automatically generated
diff --git a/opengl/tests/gl2_java/AndroidManifest.xml b/opengl/tests/gl2_java/AndroidManifest.xml
index 585b63f1..8bb6840 100644
--- a/opengl/tests/gl2_java/AndroidManifest.xml
+++ b/opengl/tests/gl2_java/AndroidManifest.xml
@@ -1,21 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/opengl/tests/gl2_java/res/values/strings.xml b/opengl/tests/gl2_java/res/values/strings.xml
index d718b1d..06bd23c 100644
--- a/opengl/tests/gl2_java/res/values/strings.xml
+++ b/opengl/tests/gl2_java/res/values/strings.xml
@@ -1,21 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 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.
-*/
+<!-- 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.
-->
<!-- This file contains resource definitions for displayed strings, allowing
diff --git a/opengl/tests/gl2_jni/AndroidManifest.xml b/opengl/tests/gl2_jni/AndroidManifest.xml
index a72a6a5..1827e5f 100644
--- a/opengl/tests/gl2_jni/AndroidManifest.xml
+++ b/opengl/tests/gl2_jni/AndroidManifest.xml
@@ -1,21 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/opengl/tests/gl2_jni/res/values/strings.xml b/opengl/tests/gl2_jni/res/values/strings.xml
index e3f7331..a29c74b 100644
--- a/opengl/tests/gl2_jni/res/values/strings.xml
+++ b/opengl/tests/gl2_jni/res/values/strings.xml
@@ -1,21 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 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.
-*/
+<!-- 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.
-->
<!-- This file contains resource definitions for displayed strings, allowing
diff --git a/opengl/tests/gl_jni/AndroidManifest.xml b/opengl/tests/gl_jni/AndroidManifest.xml
index 64bd6bf..5d0ec96 100644
--- a/opengl/tests/gl_jni/AndroidManifest.xml
+++ b/opengl/tests/gl_jni/AndroidManifest.xml
@@ -1,21 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/opengl/tests/gl_jni/res/values/strings.xml b/opengl/tests/gl_jni/res/values/strings.xml
index 880f5c9..aee9fa0 100644
--- a/opengl/tests/gl_jni/res/values/strings.xml
+++ b/opengl/tests/gl_jni/res/values/strings.xml
@@ -1,21 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 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.
-*/
+<!-- 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.
-->
<!-- This file contains resource definitions for displayed strings, allowing
diff --git a/opengl/tests/gl_perfapp/AndroidManifest.xml b/opengl/tests/gl_perfapp/AndroidManifest.xml
index 305d95f..ee4bd98 100644
--- a/opengl/tests/gl_perfapp/AndroidManifest.xml
+++ b/opengl/tests/gl_perfapp/AndroidManifest.xml
@@ -1,21 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/opengl/tests/gl_perfapp/res/values/strings.xml b/opengl/tests/gl_perfapp/res/values/strings.xml
index dc21075..52cd961 100644
--- a/opengl/tests/gl_perfapp/res/values/strings.xml
+++ b/opengl/tests/gl_perfapp/res/values/strings.xml
@@ -1,21 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 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.
-*/
+<!-- 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.
-->
<!-- This file contains resource definitions for displayed strings, allowing
diff --git a/opengl/tests/gldual/AndroidManifest.xml b/opengl/tests/gldual/AndroidManifest.xml
index 06f4c4d..a36f4f7 100644
--- a/opengl/tests/gldual/AndroidManifest.xml
+++ b/opengl/tests/gldual/AndroidManifest.xml
@@ -1,21 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/opengl/tests/gldual/res/values/strings.xml b/opengl/tests/gldual/res/values/strings.xml
index 4267dff..b1f535d 100644
--- a/opengl/tests/gldual/res/values/strings.xml
+++ b/opengl/tests/gldual/res/values/strings.xml
@@ -1,21 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 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.
-*/
+<!-- 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.
-->
<!-- This file contains resource definitions for displayed strings, allowing
diff --git a/opengl/tests/testFramerate/AndroidManifest.xml b/opengl/tests/testFramerate/AndroidManifest.xml
index e04342c..85617f4 100644
--- a/opengl/tests/testFramerate/AndroidManifest.xml
+++ b/opengl/tests/testFramerate/AndroidManifest.xml
@@ -1,21 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/opengl/tests/testFramerate/res/values/strings.xml b/opengl/tests/testFramerate/res/values/strings.xml
index e6b3088..baadf0e 100644
--- a/opengl/tests/testFramerate/res/values/strings.xml
+++ b/opengl/tests/testFramerate/res/values/strings.xml
@@ -1,21 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 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.
-*/
+<!-- 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.
-->
<!-- This file contains resource definitions for displayed strings, allowing
diff --git a/opengl/tests/testLatency/AndroidManifest.xml b/opengl/tests/testLatency/AndroidManifest.xml
index 741266e..59f2643 100644
--- a/opengl/tests/testLatency/AndroidManifest.xml
+++ b/opengl/tests/testLatency/AndroidManifest.xml
@@ -1,21 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/opengl/tests/testLatency/res/values/strings.xml b/opengl/tests/testLatency/res/values/strings.xml
index 0309991..d80b77c 100644
--- a/opengl/tests/testLatency/res/values/strings.xml
+++ b/opengl/tests/testLatency/res/values/strings.xml
@@ -1,21 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 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.
-*/
+<!-- 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.
-->
<!-- This file contains resource definitions for displayed strings, allowing
diff --git a/opengl/tests/testPauseResume/AndroidManifest.xml b/opengl/tests/testPauseResume/AndroidManifest.xml
index 3e8e7e7..1879bc3 100644
--- a/opengl/tests/testPauseResume/AndroidManifest.xml
+++ b/opengl/tests/testPauseResume/AndroidManifest.xml
@@ -1,21 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/opengl/tests/testPauseResume/res/values/strings.xml b/opengl/tests/testPauseResume/res/values/strings.xml
index 208fe15..b4c98fe2 100644
--- a/opengl/tests/testPauseResume/res/values/strings.xml
+++ b/opengl/tests/testPauseResume/res/values/strings.xml
@@ -1,21 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 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.
-*/
+<!-- 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.
-->
<!-- This file contains resource definitions for displayed strings, allowing
diff --git a/opengl/tests/testViewport/AndroidManifest.xml b/opengl/tests/testViewport/AndroidManifest.xml
index 90a9d2d..ba178bb 100644
--- a/opengl/tests/testViewport/AndroidManifest.xml
+++ b/opengl/tests/testViewport/AndroidManifest.xml
@@ -1,21 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/opengl/tests/testViewport/res/values/strings.xml b/opengl/tests/testViewport/res/values/strings.xml
index f4b8bbb..c037a7c 100644
--- a/opengl/tests/testViewport/res/values/strings.xml
+++ b/opengl/tests/testViewport/res/values/strings.xml
@@ -1,21 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 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.
-*/
+<!-- 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.
-->
<!-- This file contains resource definitions for displayed strings, allowing
diff --git a/opengl/tools/glgen/stubs/gles11/glGetString.java b/opengl/tools/glgen/stubs/gles11/glGetString.java
index d44a6dd..b02a0d1 100644
--- a/opengl/tools/glgen/stubs/gles11/glGetString.java
+++ b/opengl/tools/glgen/stubs/gles11/glGetString.java
@@ -1,21 +1,21 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- // C function const GLubyte * glGetString ( GLenum name )
-
- public static native String glGetString(
- int name
- );
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ // C function const GLubyte * glGetString ( GLenum name )
+
+ public static native String glGetString(
+ int name
+ );
diff --git a/packages/DefaultContainerService/Android.mk b/packages/DefaultContainerService/Android.mk
index 986b6c8..56b8005 100755
--- a/packages/DefaultContainerService/Android.mk
+++ b/packages/DefaultContainerService/Android.mk
@@ -7,7 +7,7 @@
LOCAL_PACKAGE_NAME := DefaultContainerService
-LOCAL_JNI_SHARED_LIBRARIES := libdefcontainer_jni
+LOCAL_REQUIRED_MODULES := libdefcontainer_jni
LOCAL_CERTIFICATE := platform
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index c3112d88..e61dd6c 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -133,6 +133,7 @@
static final boolean DEBUG = false;
static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;
static final boolean DEBUG_LAYOUT = false;
+ static final boolean DEBUG_FALLBACK = false;
static final boolean SHOW_STARTING_ANIMATIONS = true;
static final boolean SHOW_PROCESSES_ON_ALT_MENU = false;
@@ -315,8 +316,8 @@
Intent mHomeIntent;
Intent mCarDockIntent;
Intent mDeskDockIntent;
- boolean mSearchKeyPressed;
- boolean mConsumeSearchKeyUp;
+ int mShortcutKeyPressed = -1;
+ boolean mConsumeShortcutKeyUp;
boolean mShowMenuKey = false; // track FLAG_NEEDS_MENU_KEY on frontmost window
// support for activating the lock screen while the screen is on
@@ -345,6 +346,8 @@
ShortcutManager mShortcutManager;
PowerManager.WakeLock mBroadcastWakeLock;
+ final KeyCharacterMap.FallbackAction mFallbackAction = new KeyCharacterMap.FallbackAction();
+
class SettingsObserver extends ContentObserver {
SettingsObserver(Handler handler) {
super(handler);
@@ -1228,56 +1231,44 @@
+ repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed);
}
- // Clear a pending HOME longpress if the user releases Home
- // TODO: This could probably be inside the next bit of logic, but that code
- // turned out to be a bit fragile so I'm doing it here explicitly, for now.
- if ((keyCode == KeyEvent.KEYCODE_HOME) && !down) {
- mHandler.removeCallbacks(mHomeLongPress);
- }
-
- // If the HOME button is currently being held, then we do special
- // chording with it.
- if (mHomePressed) {
-
- // If we have released the home key, and didn't do anything else
- // while it was pressed, then it is time to go home!
- if (keyCode == KeyEvent.KEYCODE_HOME) {
- if (!down) {
- mHomePressed = false;
-
- if (!canceled) {
- // If an incoming call is ringing, HOME is totally disabled.
- // (The user is already on the InCallScreen at this point,
- // and his ONLY options are to answer or reject the call.)
- boolean incomingRinging = false;
- try {
- ITelephony telephonyService = getTelephonyService();
- if (telephonyService != null) {
- incomingRinging = telephonyService.isRinging();
- }
- } catch (RemoteException ex) {
- Log.w(TAG, "RemoteException from getPhoneInterface()", ex);
- }
-
- if (incomingRinging) {
- Log.i(TAG, "Ignoring HOME; there's a ringing incoming call.");
- } else {
- launchHomeFromHotKey();
- }
- } else {
- Log.i(TAG, "Ignoring HOME; event canceled.");
- }
- }
- }
-
- return true;
- }
-
// First we always handle the home key here, so applications
// can never break it, although if keyguard is on, we do let
// it handle it, because that gives us the correct 5 second
// timeout.
if (keyCode == KeyEvent.KEYCODE_HOME) {
+ // Clear a pending HOME longpress if the user releases Home
+ if (!down) {
+ mHandler.removeCallbacks(mHomeLongPress);
+ }
+
+ // If we have released the home key, and didn't do anything else
+ // while it was pressed, then it is time to go home!
+ if (mHomePressed && !down) {
+ mHomePressed = false;
+ if (!canceled) {
+ // If an incoming call is ringing, HOME is totally disabled.
+ // (The user is already on the InCallScreen at this point,
+ // and his ONLY options are to answer or reject the call.)
+ boolean incomingRinging = false;
+ try {
+ ITelephony telephonyService = getTelephonyService();
+ if (telephonyService != null) {
+ incomingRinging = telephonyService.isRinging();
+ }
+ } catch (RemoteException ex) {
+ Log.w(TAG, "RemoteException from getPhoneInterface()", ex);
+ }
+
+ if (incomingRinging) {
+ Log.i(TAG, "Ignoring HOME; there's a ringing incoming call.");
+ } else {
+ launchHomeFromHotKey();
+ }
+ } else {
+ Log.i(TAG, "Ignoring HOME; event canceled.");
+ }
+ return true;
+ }
// If a system window has focus, then it doesn't make sense
// right now to interact with applications.
@@ -1334,21 +1325,28 @@
} else if (keyCode == KeyEvent.KEYCODE_SEARCH) {
if (down) {
if (repeatCount == 0) {
- mSearchKeyPressed = true;
+ mShortcutKeyPressed = keyCode;
+ mConsumeShortcutKeyUp = false;
}
- } else {
- mSearchKeyPressed = false;
+ } else if (keyCode == mShortcutKeyPressed) {
+ mShortcutKeyPressed = -1;
- if (mConsumeSearchKeyUp) {
+ if (mConsumeShortcutKeyUp) {
// Consume the up-event
- mConsumeSearchKeyUp = false;
+ mConsumeShortcutKeyUp = false;
return true;
}
}
+ } else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) {
+ if (!down) {
+ showRecentAppsDialog();
+ }
+ return true;
}
- // Shortcuts are invoked through Search+key, so intercept those here
- if (mSearchKeyPressed) {
+ // Shortcuts are invoked through Search+key or Meta+key, so intercept those here
+ if ((mShortcutKeyPressed != -1 && !mConsumeShortcutKeyUp)
+ || (metaState & KeyEvent.META_META_ON) != 0) {
if (down && repeatCount == 0 && !keyguardOn) {
Intent shortcutIntent = mShortcutManager.getIntent(event);
if (shortcutIntent != null) {
@@ -1359,7 +1357,9 @@
* We launched an app, so the up-event of the search key
* should be consumed
*/
- mConsumeSearchKeyUp = true;
+ if (mShortcutKeyPressed != -1) {
+ mConsumeShortcutKeyUp = true;
+ }
return true;
}
}
@@ -1370,8 +1370,8 @@
/** {@inheritDoc} */
@Override
- public boolean dispatchUnhandledKey(WindowState win, KeyEvent event, int policyFlags) {
- if (false) {
+ public KeyEvent dispatchUnhandledKey(WindowState win, KeyEvent event, int policyFlags) {
+ if (DEBUG_FALLBACK) {
Slog.d(TAG, "Unhandled key: win=" + win + ", action=" + event.getAction()
+ ", flags=" + event.getFlags()
+ ", keyCode=" + event.getKeyCode()
@@ -1380,7 +1380,42 @@
+ ", repeatCount=" + event.getRepeatCount()
+ ", policyFlags=" + policyFlags);
}
- return false;
+
+ if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
+ final KeyCharacterMap kcm = event.getKeyCharacterMap();
+ boolean fallback = kcm.getFallbackAction(event.getKeyCode(), event.getMetaState(),
+ mFallbackAction);
+
+ if (fallback) {
+ if (DEBUG_FALLBACK) {
+ Slog.d(TAG, "Fallback: keyCode=" + mFallbackAction.keyCode
+ + " metaState=" + Integer.toHexString(mFallbackAction.metaState));
+ }
+
+ int flags = event.getFlags() | KeyEvent.FLAG_FALLBACK;
+ KeyEvent fallbackEvent = KeyEvent.obtain(
+ event.getDownTime(), event.getEventTime(),
+ event.getAction(), mFallbackAction.keyCode,
+ event.getRepeatCount(), mFallbackAction.metaState,
+ event.getDeviceId(), event.getScanCode(),
+ flags, event.getSource(), null);
+ int actions = interceptKeyBeforeQueueing(fallbackEvent, policyFlags, true);
+ if ((actions & ACTION_PASS_TO_USER) != 0) {
+ if (!interceptKeyBeforeDispatching(win, fallbackEvent, policyFlags)) {
+ if (DEBUG_FALLBACK) {
+ Slog.d(TAG, "Performing fallback.");
+ }
+ return fallbackEvent;
+ }
+ }
+ fallbackEvent.recycle();
+ }
+ }
+
+ if (DEBUG_FALLBACK) {
+ Slog.d(TAG, "No fallback.");
+ }
+ return null;
}
/**
diff --git a/services/java/com/android/server/InputManager.java b/services/java/com/android/server/InputManager.java
index 8634eec..4c499cd 100644
--- a/services/java/com/android/server/InputManager.java
+++ b/services/java/com/android/server/InputManager.java
@@ -402,7 +402,7 @@
}
@SuppressWarnings("unused")
- public boolean dispatchUnhandledKey(InputChannel focus,
+ public KeyEvent dispatchUnhandledKey(InputChannel focus,
KeyEvent event, int policyFlags) {
return mWindowManagerService.mInputMonitor.dispatchUnhandledKey(
focus, event, policyFlags);
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 2d88b2f..f78ebb9 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -5844,7 +5844,7 @@
/* Provides an opportunity for the window manager policy to process a key that
* the application did not handle. */
- public boolean dispatchUnhandledKey(
+ public KeyEvent dispatchUnhandledKey(
InputChannel focus, KeyEvent event, int policyFlags) {
WindowState windowState = getWindowStateForInputChannel(focus);
return mPolicy.dispatchUnhandledKey(windowState, event, policyFlags);
diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp
index 1996dd0..9156249 100644
--- a/services/jni/com_android_server_InputManager.cpp
+++ b/services/jni/com_android_server_InputManager.cpp
@@ -183,7 +183,7 @@
virtual bool interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
const KeyEvent* keyEvent, uint32_t policyFlags);
virtual bool dispatchUnhandledKey(const sp<InputChannel>& inputChannel,
- const KeyEvent* keyEvent, uint32_t policyFlags);
+ const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent);
virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType);
virtual bool checkInjectEventsPermissionNonReentrant(
int32_t injectorPid, int32_t injectorUid);
@@ -813,7 +813,7 @@
// - Ignore untrusted events and pass them along.
// - Filter normal events and trusted injected events through the window manager policy to
// handle the HOME key and the like.
- bool result;
+ bool result = false;
if (policyFlags & POLICY_FLAG_TRUSTED) {
JNIEnv* env = jniEnv();
@@ -830,21 +830,17 @@
result = consumed && !error;
} else {
LOGE("Failed to obtain key event object for interceptKeyBeforeDispatching.");
- result = false;
}
-
env->DeleteLocalRef(inputChannelObj);
- } else {
- result = false;
}
return result;
}
bool NativeInputManager::dispatchUnhandledKey(const sp<InputChannel>& inputChannel,
- const KeyEvent* keyEvent, uint32_t policyFlags) {
+ const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
// Policy:
// - Ignore untrusted events and do not perform default handling.
- bool result;
+ bool result = false;
if (policyFlags & POLICY_FLAG_TRUSTED) {
JNIEnv* env = jniEnv();
@@ -852,21 +848,26 @@
jobject inputChannelObj = getInputChannelObjLocal(env, inputChannel);
jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
if (keyEventObj) {
- jboolean handled = env->CallBooleanMethod(mCallbacksObj,
+ jobject fallbackKeyEventObj = env->CallObjectMethod(mCallbacksObj,
gCallbacksClassInfo.dispatchUnhandledKey,
inputChannelObj, keyEventObj, policyFlags);
- bool error = checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey");
+ checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey");
android_view_KeyEvent_recycle(env, keyEventObj);
env->DeleteLocalRef(keyEventObj);
- result = handled && !error;
+
+ if (fallbackKeyEventObj) {
+ // Note: outFallbackKeyEvent may be the same object as keyEvent.
+ if (!android_view_KeyEvent_toNative(env, fallbackKeyEventObj,
+ outFallbackKeyEvent)) {
+ result = true;
+ }
+ android_view_KeyEvent_recycle(env, fallbackKeyEventObj);
+ env->DeleteLocalRef(fallbackKeyEventObj);
+ }
} else {
LOGE("Failed to obtain key event object for dispatchUnhandledKey.");
- result = false;
}
-
env->DeleteLocalRef(inputChannelObj);
- } else {
- result = false;
}
return result;
}
@@ -1307,7 +1308,8 @@
"(Landroid/view/InputChannel;Landroid/view/KeyEvent;I)Z");
GET_METHOD_ID(gCallbacksClassInfo.dispatchUnhandledKey, gCallbacksClassInfo.clazz,
- "dispatchUnhandledKey", "(Landroid/view/InputChannel;Landroid/view/KeyEvent;I)Z");
+ "dispatchUnhandledKey",
+ "(Landroid/view/InputChannel;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, gCallbacksClassInfo.clazz,
"checkInjectEventsPermission", "(II)Z");
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 145618e..15df888 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -409,6 +409,7 @@
err = buffer->initCheck();
if (err || buffer->handle == 0) {
+ GraphicBuffer::dumpAllocationsToSystemLog();
LOGE_IF(err || buffer->handle == 0,
"Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)",
this, index, w, h, strerror(-err));
diff --git a/tests/DumpRenderTree/AndroidManifest.xml b/tests/DumpRenderTree/AndroidManifest.xml
index 86b3f06..dc44b25 100644
--- a/tests/DumpRenderTree/AndroidManifest.xml
+++ b/tests/DumpRenderTree/AndroidManifest.xml
@@ -27,7 +27,7 @@
</activity>
<activity android:name="TestShellActivity"
android:launchMode="singleTop"
- android:hardwareAccelerated="false"
+ android:hardwareAccelerated="true"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Light"/>
<activity android:name="ReliabilityTestActivity" android:screenOrientation="portrait"
diff --git a/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java b/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java
new file mode 100644
index 0000000..7d41d1c
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java
@@ -0,0 +1,54 @@
+/*
+ * 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 android.animation;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+
+/**
+ * Delegate implementing the native methods of android.animation.PropertyValuesHolder
+ *
+ * Through the layoutlib_create tool, the original native methods of PropertyValuesHolder have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
+ * around to map int to instance of the delegate.
+ *
+ * The main goal of this class' methods are to provide a native way to access setters and getters
+ * on some object. In this case we want to default to using Java reflection instead so the native
+ * methods do nothing.
+ *
+ */
+/*package*/ class PropertyValuesHolder_Delegate {
+
+ /*package*/ static int nGetIntMethod(Class<?> targetClass, String methodName) {
+ // return 0 to force PropertyValuesHolder to use Java reflection.
+ return 0;
+ }
+
+ /*package*/ static int nGetFloatMethod(Class<?> targetClass, String methodName) {
+ // return 0 to force PropertyValuesHolder to use Java reflection.
+ return 0;
+ }
+
+ /*package*/ static void nCallIntMethod(Object target, int methodID, int arg) {
+ // do nothing
+ }
+
+ /*package*/ static void nCallFloatMethod(Object target, int methodID, float arg) {
+ // do nothing
+ }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java
index d58cde8..0130970 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java
@@ -458,16 +458,10 @@
mCanvas.setDensity(mParams.getDensity());
}
- long preDrawTime = System.currentTimeMillis();
-
mViewRoot.draw(mCanvas);
- long drawTime = System.currentTimeMillis();
-
mViewInfo = visit(((ViewGroup)mViewRoot).getChildAt(0), mContext);
- System.out.println(String.format("rendering (ms): %03d", drawTime - preDrawTime));
-
// success!
return SceneStatus.SUCCESS.createResult();
} catch (Throwable e) {
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index 4440685..1d40d33 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -105,6 +105,7 @@
* The list of classes on which to delegate all native methods.
*/
private final static String[] DELEGATE_CLASS_NATIVES = new String[] {
+ "android.animation.PropertyValuesHolder",
"android.graphics.Bitmap",
"android.graphics.Canvas",
"android.graphics.DashPathEffect",