Merge "Some fixes to the new loader management."
diff --git a/api/current.xml b/api/current.xml
index a80a702..f915fad 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -3265,6 +3265,17 @@
visibility="public"
>
</field>
+<field name="customTokens"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843593"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="cycles"
type="int"
transient="false"
@@ -18308,6 +18319,28 @@
visibility="public"
>
</field>
+<field name="KEY_CALLER_PID"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""callerPid""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="KEY_CALLER_UID"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""callerUid""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="KEY_ERROR_CODE"
type="java.lang.String"
transient="false"
@@ -18555,6 +18588,28 @@
</parameter>
<parameter name="prefId" type="int">
</parameter>
+<parameter name="customTokens" type="boolean">
+</parameter>
+</constructor>
+<constructor name="AuthenticatorDescription"
+ type="android.accounts.AuthenticatorDescription"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="type" type="java.lang.String">
+</parameter>
+<parameter name="packageName" type="java.lang.String">
+</parameter>
+<parameter name="labelId" type="int">
+</parameter>
+<parameter name="iconId" type="int">
+</parameter>
+<parameter name="smallIconId" type="int">
+</parameter>
+<parameter name="prefId" type="int">
+</parameter>
</constructor>
<method name="describeContents"
return="int"
@@ -18615,6 +18670,16 @@
visibility="public"
>
</field>
+<field name="customTokens"
+ type="boolean"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="iconId"
type="int"
transient="false"
@@ -223231,7 +223296,7 @@
abstract="false"
static="false"
final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
<constructor name="CacheManager"
@@ -223322,7 +223387,7 @@
abstract="false"
static="true"
final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
<constructor name="CacheManager.CacheResult"
diff --git a/core/java/android/accounts/AccountAuthenticatorCache.java b/core/java/android/accounts/AccountAuthenticatorCache.java
index 524d3f4..7214c50 100644
--- a/core/java/android/accounts/AccountAuthenticatorCache.java
+++ b/core/java/android/accounts/AccountAuthenticatorCache.java
@@ -38,7 +38,7 @@
* @hide
*/
/* package private */ class AccountAuthenticatorCache
- extends RegisteredServicesCache<AuthenticatorDescription>
+ extends RegisteredServicesCache<AuthenticatorDescription>
implements IAccountAuthenticatorCache {
private static final String TAG = "Account";
private static final MySerializer sSerializer = new MySerializer();
@@ -64,11 +64,13 @@
com.android.internal.R.styleable.AccountAuthenticator_smallIcon, 0);
final int prefId = sa.getResourceId(
com.android.internal.R.styleable.AccountAuthenticator_accountPreferences, 0);
+ final boolean customTokens = sa.getBoolean(
+ com.android.internal.R.styleable.AccountAuthenticator_customTokens, false);
if (TextUtils.isEmpty(accountType)) {
return null;
}
- return new AuthenticatorDescription(accountType, packageName, labelId, iconId,
- smallIconId, prefId);
+ return new AuthenticatorDescription(accountType, packageName, labelId, iconId,
+ smallIconId, prefId, customTokens);
} finally {
sa.recycle();
}
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index fd3a0d0..6388dc5 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -188,6 +188,12 @@
public static final String KEY_ERROR_CODE = "errorCode";
public static final String KEY_ERROR_MESSAGE = "errorMessage";
public static final String KEY_USERDATA = "userdata";
+ /**
+ * Authenticators using 'customTokens' option will also get the UID of the
+ * caller
+ */
+ public static final String KEY_CALLER_UID = "callerUid";
+ public static final String KEY_CALLER_PID = "callerPid";
public static final String ACTION_AUTHENTICATOR_INTENT =
"android.accounts.AccountAuthenticator";
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index a815b3a..72da2ce 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -82,8 +82,6 @@
implements RegisteredServicesCacheListener<AuthenticatorDescription> {
private static final String GOOGLE_ACCOUNT_TYPE = "com.google";
- private static final String NO_BROADCAST_FLAG = "nobroadcast";
-
private static final String TAG = "AccountManagerService";
private static final int TIMEOUT_DELAY_MS = 1000 * 60;
@@ -375,14 +373,6 @@
if (account == null) {
return false;
}
- final boolean noBroadcast = account.type.equals(GOOGLE_ACCOUNT_TYPE)
- && extras != null && extras.getBoolean(NO_BROADCAST_FLAG, false);
- // Remove the 'nobroadcast' flag since we don't want it to persist in the db. It is instead
- // used as a control signal to indicate whether or not this insertion should result in
- // an accounts changed broadcast being sent.
- if (extras != null) {
- extras.remove(NO_BROADCAST_FLAG);
- }
db.beginTransaction();
try {
long numMatches = DatabaseUtils.longForQuery(db,
@@ -419,9 +409,7 @@
} finally {
db.endTransaction();
}
- if (!noBroadcast) {
- sendAccountsChangedBroadcast();
- }
+ sendAccountsChangedBroadcast();
return true;
}
@@ -776,10 +764,6 @@
if (account == null) throw new IllegalArgumentException("account is null");
checkAuthenticateAccountsPermission(account);
long identityToken = clearCallingIdentity();
- if (account.type.equals(GOOGLE_ACCOUNT_TYPE) && key.equals("broadcast")) {
- sendAccountsChangedBroadcast();
- return;
- }
try {
writeUserdataIntoDatabase(account, key, value);
} finally {
@@ -893,13 +877,29 @@
if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
checkBinderPermission(Manifest.permission.USE_CREDENTIALS);
final int callerUid = Binder.getCallingUid();
- final boolean permissionGranted = permissionIsGranted(account, authTokenType, callerUid);
+ final int callerPid = Binder.getCallingPid();
+
+ AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticatorInfo =
+ mAuthenticatorCache.getServiceInfo(
+ AuthenticatorDescription.newKey(account.type));
+ final boolean customTokens =
+ authenticatorInfo != null && authenticatorInfo.type.customTokens;
+
+ // skip the check if customTokens
+ final boolean permissionGranted = customTokens ||
+ permissionIsGranted(account, authTokenType, callerUid);
+
+ if (customTokens) {
+ // let authenticator know the identity of the caller
+ loginOptions.putInt(AccountManager.KEY_CALLER_UID, callerUid);
+ loginOptions.putInt(AccountManager.KEY_CALLER_PID, callerPid);
+ }
long identityToken = clearCallingIdentity();
try {
// if the caller has permission, do the peek. otherwise go the more expensive
// route of starting a Session
- if (permissionGranted) {
+ if (!customTokens && permissionGranted) {
String authToken = readAuthTokenFromCache(account, authTokenType);
if (authToken != null) {
Bundle result = new Bundle();
@@ -953,8 +953,10 @@
"the type and name should not be empty");
return;
}
- saveAuthTokenToDatabase(new Account(name, type),
- authTokenType, authToken);
+ if (!customTokens) {
+ saveAuthTokenToDatabase(new Account(name, type),
+ authTokenType, authToken);
+ }
}
Intent intent = result.getParcelable(AccountManager.KEY_INTENT);
diff --git a/core/java/android/accounts/AuthenticatorDescription.java b/core/java/android/accounts/AuthenticatorDescription.java
index c6515672..5d9abb0 100644
--- a/core/java/android/accounts/AuthenticatorDescription.java
+++ b/core/java/android/accounts/AuthenticatorDescription.java
@@ -44,9 +44,12 @@
/** The package name that can be used to lookup the resources from above. */
final public String packageName;
+ /** Authenticator handles its own token caching and permission screen */
+ final public boolean customTokens;
+
/** A constructor for a full AuthenticatorDescription */
public AuthenticatorDescription(String type, String packageName, int labelId, int iconId,
- int smallIconId, int prefId) {
+ int smallIconId, int prefId, boolean customTokens) {
if (type == null) throw new IllegalArgumentException("type cannot be null");
if (packageName == null) throw new IllegalArgumentException("packageName cannot be null");
this.type = type;
@@ -55,6 +58,12 @@
this.iconId = iconId;
this.smallIconId = smallIconId;
this.accountPreferencesId = prefId;
+ this.customTokens = customTokens;
+ }
+
+ public AuthenticatorDescription(String type, String packageName, int labelId, int iconId,
+ int smallIconId, int prefId) {
+ this(type, packageName, labelId, iconId, smallIconId, prefId, false);
}
/**
@@ -74,6 +83,7 @@
this.iconId = 0;
this.smallIconId = 0;
this.accountPreferencesId = 0;
+ this.customTokens = false;
}
private AuthenticatorDescription(Parcel source) {
@@ -83,6 +93,7 @@
this.iconId = source.readInt();
this.smallIconId = source.readInt();
this.accountPreferencesId = source.readInt();
+ this.customTokens = source.readByte() == 1;
}
/** @inheritDoc */
@@ -115,6 +126,7 @@
dest.writeInt(iconId);
dest.writeInt(smallIconId);
dest.writeInt(accountPreferencesId);
+ dest.writeByte((byte) (customTokens ? 1 : 0));
}
/** Used to create the object from a parcel. */
diff --git a/core/java/android/app/AlertDialog.java b/core/java/android/app/AlertDialog.java
index 5dc29a9..d9cafb6 100644
--- a/core/java/android/app/AlertDialog.java
+++ b/core/java/android/app/AlertDialog.java
@@ -24,7 +24,6 @@
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Message;
-import android.util.Log;
import android.util.TypedValue;
import android.view.ContextThemeWrapper;
import android.view.KeyEvent;
diff --git a/core/java/android/app/DatePickerDialog.java b/core/java/android/app/DatePickerDialog.java
index efe527f..448b3ef 100644
--- a/core/java/android/app/DatePickerDialog.java
+++ b/core/java/android/app/DatePickerDialog.java
@@ -71,10 +71,7 @@
int year,
int monthOfYear,
int dayOfMonth) {
- this(context, context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB
- ? com.android.internal.R.style.Theme_Holo_Dialog_Alert
- : com.android.internal.R.style.Theme_Dialog_Alert,
- callBack, year, monthOfYear, dayOfMonth);
+ this(context, 0, callBack, year, monthOfYear, dayOfMonth);
}
/**
diff --git a/core/java/android/app/TimePickerDialog.java b/core/java/android/app/TimePickerDialog.java
index 26af4eb..f9920c7 100644
--- a/core/java/android/app/TimePickerDialog.java
+++ b/core/java/android/app/TimePickerDialog.java
@@ -21,7 +21,6 @@
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
-import android.os.Build;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
@@ -72,11 +71,7 @@
public TimePickerDialog(Context context,
OnTimeSetListener callBack,
int hourOfDay, int minute, boolean is24HourView) {
- this(context,
- context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB
- ? com.android.internal.R.style.Theme_Holo_Dialog_Alert
- : com.android.internal.R.style.Theme_Dialog_Alert,
- callBack, hourOfDay, minute, is24HourView);
+ this(context, 0, callBack, hourOfDay, minute, is24HourView);
}
/**
diff --git a/core/java/android/content/SyncActivityTooManyDeletes.java b/core/java/android/content/SyncActivityTooManyDeletes.java
new file mode 100644
index 0000000..350f35e
--- /dev/null
+++ b/core/java/android/content/SyncActivityTooManyDeletes.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content;
+
+import com.android.internal.R;
+import android.accounts.Account;
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.LinearLayout;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+/**
+ * Presents multiple options for handling the case where a sync was aborted because there
+ * were too many pending deletes. One option is to force the delete, another is to rollback
+ * the deletes, the third is to do nothing.
+ * @hide
+ */
+public class SyncActivityTooManyDeletes extends Activity
+ implements AdapterView.OnItemClickListener {
+
+ private long mNumDeletes;
+ private Account mAccount;
+ private String mAuthority;
+ private String mProvider;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ Bundle extras = getIntent().getExtras();
+ if (extras == null) {
+ finish();
+ return;
+ }
+
+ mNumDeletes = extras.getLong("numDeletes");
+ mAccount = (Account) extras.getParcelable("account");
+ mAuthority = extras.getString("authority");
+ mProvider = extras.getString("provider");
+
+ // the order of these must match up with the constants for position used in onItemClick
+ CharSequence[] options = new CharSequence[]{
+ getResources().getText(R.string.sync_really_delete),
+ getResources().getText(R.string.sync_undo_deletes),
+ getResources().getText(R.string.sync_do_nothing)
+ };
+
+ ListAdapter adapter = new ArrayAdapter<CharSequence>(this,
+ android.R.layout.simple_list_item_1,
+ android.R.id.text1,
+ options);
+
+ ListView listView = new ListView(this);
+ listView.setAdapter(adapter);
+ listView.setItemsCanFocus(true);
+ listView.setOnItemClickListener(this);
+
+ TextView textView = new TextView(this);
+ CharSequence tooManyDeletesDescFormat =
+ getResources().getText(R.string.sync_too_many_deletes_desc);
+ textView.setText(String.format(tooManyDeletesDescFormat.toString(),
+ mNumDeletes, mProvider, mAccount.name));
+
+ final LinearLayout ll = new LinearLayout(this);
+ ll.setOrientation(LinearLayout.VERTICAL);
+ final LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, 0);
+ ll.addView(textView, lp);
+ ll.addView(listView, lp);
+
+ // TODO: consider displaying the icon of the account type
+// AuthenticatorDescription[] descs = AccountManager.get(this).getAuthenticatorTypes();
+// for (AuthenticatorDescription desc : descs) {
+// if (desc.type.equals(mAccount.type)) {
+// try {
+// final Context authContext = createPackageContext(desc.packageName, 0);
+// ImageView imageView = new ImageView(this);
+// imageView.setImageDrawable(authContext.getResources().getDrawable(desc.iconId));
+// ll.addView(imageView, lp);
+// } catch (PackageManager.NameNotFoundException e) {
+// }
+// break;
+// }
+// }
+
+ setContentView(ll);
+ }
+
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ // the constants for position correspond to the items options array in onCreate()
+ if (position == 0) startSyncReallyDelete();
+ else if (position == 1) startSyncUndoDeletes();
+ finish();
+ }
+
+ private void startSyncReallyDelete() {
+ Bundle extras = new Bundle();
+ extras.putBoolean(ContentResolver.SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS, true);
+ extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
+ extras.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
+ extras.putBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, true);
+ ContentResolver.requestSync(mAccount, mAuthority, extras);
+ }
+
+ private void startSyncUndoDeletes() {
+ Bundle extras = new Bundle();
+ extras.putBoolean(ContentResolver.SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS, true);
+ extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
+ extras.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
+ extras.putBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, true);
+ ContentResolver.requestSync(mAccount, mAuthority, extras);
+ }
+}
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 599429b..8b292c9 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -2157,9 +2157,7 @@
}
CharSequence authorityName = providerInfo.loadLabel(mContext.getPackageManager());
- Intent clickIntent = new Intent();
- clickIntent.setClassName("com.android.providers.subscribedfeeds",
- "com.android.settings.SyncActivityTooManyDeletes");
+ Intent clickIntent = new Intent(mContext, SyncActivityTooManyDeletes.class);
clickIntent.putExtra("account", account);
clickIntent.putExtra("authority", authority);
clickIntent.putExtra("provider", authorityName.toString());
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index d27e99d..75aebc9 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -8206,8 +8206,9 @@
/**
* Manually render this view (and all of its children) to the given Canvas.
* The view must have already done a full layout before this function is
- * called. When implementing a view, do not override this method; instead,
- * you should implement {@link #onDraw}.
+ * called. When implementing a view, implement {@link #onDraw} instead of
+ * overriding this method. If you do need to override this method, call
+ * the superclass version.
*
* @param canvas The Canvas to which the View is rendered.
*/
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 6309cac..0deb0a0 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -5184,6 +5184,8 @@
public void onRemoteAdapterConnected() {
if (mRemoteAdapter != mAdapter) {
setAdapter(mRemoteAdapter);
+ } else if (mRemoteAdapter != null) {
+ mRemoteAdapter.superNotifyDataSetChanged();
}
}
@@ -5191,10 +5193,11 @@
* Called back when the adapter disconnects from the RemoteViewsService.
*/
public void onRemoteAdapterDisconnected() {
- if (mRemoteAdapter == mAdapter) {
- mRemoteAdapter = null;
- setAdapter(null);
- }
+ // If the remote adapter disconnects, we keep it around
+ // since the currently displayed items are still cached.
+ // Further, we want the service to eventually reconnect
+ // when necessary, as triggered by this view requesting
+ // items from the Adapter.
}
/**
diff --git a/core/java/android/widget/AdapterViewAnimator.java b/core/java/android/widget/AdapterViewAnimator.java
index 162b030..ec8e93c 100644
--- a/core/java/android/widget/AdapterViewAnimator.java
+++ b/core/java/android/widget/AdapterViewAnimator.java
@@ -964,6 +964,8 @@
public void onRemoteAdapterConnected() {
if (mRemoteViewsAdapter != mAdapter) {
setAdapter(mRemoteViewsAdapter);
+ } else if (mRemoteViewsAdapter != null) {
+ mRemoteViewsAdapter.superNotifyDataSetChanged();
}
}
@@ -971,10 +973,11 @@
* Called back when the adapter disconnects from the RemoteViewsService.
*/
public void onRemoteAdapterDisconnected() {
- if (mRemoteViewsAdapter != mAdapter) {
- mRemoteViewsAdapter = null;
- setAdapter(mRemoteViewsAdapter);
- }
+ // If the remote adapter disconnects, we keep it around
+ // since the currently displayed items are still cached.
+ // Further, we want the service to eventually reconnect
+ // when necessary, as triggered by this view requesting
+ // items from the Adapter.
}
public void advance() {
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 3703846..6894c99 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -103,7 +103,7 @@
Drawable mDivider;
int mDividerHeight;
-
+
Drawable mOverScrollHeader;
Drawable mOverScrollFooter;
@@ -1535,7 +1535,6 @@
// reset the focus restoration
View focusLayoutRestoreDirectChild = null;
-
// Don't put header or footer views into the Recycler. Those are
// already cached in mHeaderViews;
if (dataChanged) {
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 7b35b51..8c22f97 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -534,7 +534,7 @@
});
// create the fling and adjust scrollers
- mFlingScroller = new Scroller(getContext());
+ mFlingScroller = new Scroller(getContext(), null, true);
mAdjustScroller = new Scroller(getContext(), new OvershootInterpolator());
updateInputTextView();
@@ -798,6 +798,7 @@
*/
public void setFormatter(Formatter formatter) {
mFormatter = formatter;
+ resetSelectorIndices();
}
/**
@@ -979,10 +980,7 @@
// children
// after we have completed drawing ourselves.
- // Draw the selector wheel if needed
- if (mDrawSelectorWheel) {
- super.draw(canvas);
- }
+ super.draw(canvas);
// Draw our children if we are not showing the selector wheel of fading
// it out
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index 52d9c08..a7bff62 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -148,11 +148,6 @@
adapter.mMainQueue.removeMessages(0);
adapter.mWorkerQueue.removeMessages(0);
- // Clear the cache (the meta data will be re-requested on service re-connection)
- synchronized (adapter.mCache) {
- adapter.mCache.reset();
- }
-
final RemoteAdapterConnectionCallback callback = adapter.mCallback.get();
if (callback != null) {
callback.onRemoteAdapterDisconnected();
@@ -335,8 +330,8 @@
// Compose the loading view text
TextView loadingTextView = (TextView) mLayoutInflater.inflate(
- com.android.internal.R.layout.remote_views_adapter_default_loading_view,
- layout, false);
+ com.android.internal.R.layout.remote_views_adapter_default_loading_view,
+ layout, false);
loadingTextView.setHeight(mFirstViewHeight);
loadingTextView.setTag(new Integer(0));
@@ -880,7 +875,7 @@
// a chance to update itself and return new meta data associated with the new data.
}
- private void superNotifyDataSetChanged() {
+ void superNotifyDataSetChanged() {
super.notifyDataSetChanged();
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 9a2cc89..4fdadab 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -864,6 +864,7 @@
mInputType = EditorInfo.TYPE_NULL;
mInput = null;
bufferType = BufferType.SPANNABLE;
+ // Required to request focus while in touch mode.
setFocusableInTouchMode(true);
// So that selection can be changed using arrow keys and touch is handled.
setMovementMethod(ArrowKeyMovementMethod.getInstance());
@@ -2748,7 +2749,10 @@
*/
mText = text;
- if (mLinksClickable) {
+ // Do not change the movement method for text that support text selection as it
+ // would prevent an arbitrary cursor displacement.
+ final boolean hasTextSelection = this instanceof EditText || mTextIsSelectable;
+ if (mLinksClickable && !hasTextSelection) {
setMovementMethod(LinkMovementMethod.getInstance());
}
}
@@ -3876,7 +3880,7 @@
// - ExtractEditText does not call onFocus when it is displayed. Fixing this issue would
// allow to test for hasSelection in onFocusChanged, which would trigger a
// startTextSelectionMode here. TODO
- if (this instanceof ExtractEditText && hasSelection() && hasSelectionController()) {
+ if (this instanceof ExtractEditText && hasSelection() && canSelectText()) {
startSelectionActionMode();
}
@@ -4073,7 +4077,7 @@
*
* Use {@link #setTextIsSelectable(boolean)} or the
* {@link android.R.styleable#TextView_textIsSelectable} XML attribute to make this TextView
- * selectable (the text is not selectable by default).
+ * selectable (text is not selectable by default).
*
* Note that the content of an EditText is always selectable.
*
@@ -4088,8 +4092,8 @@
/**
* Sets whether or not (default) the content of this view is selectable by the user.
*
- * Note that this methods affect the {@link #setFocusableInTouchMode(boolean)},
- * {@link #setFocusable(boolean)}, {@link #setClickable(boolean)} and
+ * Note that this methods affect the {@link #setFocusable(boolean)},
+ * {@link #setFocusableInTouchMode(boolean)} {@link #setClickable(boolean)} and
* {@link #setLongClickable(boolean)} states and you may want to restore these if they were
* customized.
*
@@ -7519,10 +7523,21 @@
return super.onKeyShortcut(keyCode, event);
}
+ /**
+ * Unlike {@link #textCanBeSelected()}, this method is based on the <i>current</i> state of the
+ * TextView. {@link #textCanBeSelected()} has to be true (this is one of the conditions to have
+ * a selection controller (see {@link #prepareCursorControllers()}), but this is not sufficient.
+ */
private boolean canSelectText() {
return hasSelectionController() && mText.length() != 0;
}
+ /**
+ * Test based on the <i>intrinsic</i> charateristics of the TextView.
+ * The text must be spannable and the movement method must allow for arbitary selection.
+ *
+ * See also {@link #canSelectText()}.
+ */
private boolean textCanBeSelected() {
// prepareCursorController() relies on this method.
// If you change this condition, make sure prepareCursorController is called anywhere
@@ -7753,11 +7768,12 @@
boolean added = false;
mContextMenuTriggeredByKey = mDPadCenterIsDown || mEnterKeyIsDown;
// Problem with context menu on long press: the menu appears while the key in down and when
- // the key is released, the view does not receive the key_up event. This ensures that the
- // state is reset whenever the context menu action is displayed.
- // mContextMenuTriggeredByKey saved that state so that it is available in
- // onTextContextMenuItem. We cannot simply clear these flags in onTextContextMenuItem since
+ // the key is released, the view does not receive the key_up event.
+ // We need two layers of flags: mDPadCenterIsDown and mEnterKeyIsDown are set in key down/up
+ // events. We cannot simply clear these flags in onTextContextMenuItem since
// it may not be called (if the user/ discards the context menu with the back key).
+ // We clear these flags here and mContextMenuTriggeredByKey saves that state so that it is
+ // available in onTextContextMenuItem.
mDPadCenterIsDown = mEnterKeyIsDown = false;
MenuHandler handler = new MenuHandler();
@@ -7769,12 +7785,10 @@
int min = Math.min(selStart, selEnd);
int max = Math.max(selStart, selEnd);
- URLSpan[] urls = ((Spanned) mText).getSpans(min, max,
- URLSpan.class);
- if (urls.length == 1) {
- menu.add(0, ID_COPY_URL, 0,
- com.android.internal.R.string.copyUrl).
- setOnMenuItemClickListener(handler);
+ URLSpan[] urls = ((Spanned) mText).getSpans(min, max, URLSpan.class);
+ if (urls.length > 0) {
+ menu.add(0, ID_COPY_URL, 0, com.android.internal.R.string.copyUrl).
+ setOnMenuItemClickListener(handler);
added = true;
}
@@ -7786,7 +7800,7 @@
// populates the menu AFTER this call.
if (menu.size() > 0) {
menu.add(0, ID_SELECTION_MODE, 0, com.android.internal.R.string.selectTextMode).
- setOnMenuItemClickListener(handler);
+ setOnMenuItemClickListener(handler);
added = true;
}
@@ -8063,6 +8077,11 @@
return false;
}
+ if (!canSelectText() || !requestFocus()) {
+ Log.w(LOG_TAG, "TextView does not support text selection. Action mode cancelled.");
+ return false;
+ }
+
selectCurrentWord();
final InputMethodManager imm = (InputMethodManager)
getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
@@ -8139,26 +8158,15 @@
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
- if (!hasSelectionController()) {
- Log.w(LOG_TAG, "TextView has no selection controller. Action mode cancelled.");
- return false;
- }
-
- if (!requestFocus()) {
- return false;
- }
-
TypedArray styledAttributes = mContext.obtainStyledAttributes(R.styleable.Theme);
mode.setTitle(mContext.getString(com.android.internal.R.string.textSelectionCABTitle));
mode.setSubtitle(null);
- if (canSelectText()) {
- menu.add(0, ID_SELECT_ALL, 0, com.android.internal.R.string.selectAll).
+ menu.add(0, ID_SELECT_ALL, 0, com.android.internal.R.string.selectAll).
setAlphabeticShortcut('a').
setShowAsAction(
MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
- }
if (canCut()) {
menu.add(0, ID_CUT, 0, com.android.internal.R.string.cut).
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index 3a58867..633bdd3 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -505,12 +505,13 @@
}
mContainerView.setVisibility(View.VISIBLE);
mContainerView.setAlpha(0);
- mContainerView.setTranslationY(-mContainerView.getHeight());
AnimatorSet anim = new AnimatorSet();
- AnimatorSet.Builder b = anim.play(ObjectAnimator.ofFloat(mContainerView, "translationY", 0))
- .with(ObjectAnimator.ofFloat(mContainerView, "alpha", 1));
+ AnimatorSet.Builder b = anim.play(ObjectAnimator.ofFloat(mContainerView, "alpha", 1));
if (mContentView != null) {
- b.with(ObjectAnimator.ofFloat(mContentView, "translationY", -mContainerView.getHeight(), 0));
+ b.with(ObjectAnimator.ofFloat(mContentView, "translationY",
+ -mContainerView.getHeight(), 0));
+ mContainerView.setTranslationY(-mContainerView.getHeight());
+ b.with(ObjectAnimator.ofFloat(mContainerView, "translationY", 0));
}
anim.addListener(mShowListener);
mCurrentAnim = anim;
@@ -527,11 +528,12 @@
}
mContainerView.setAlpha(1);
AnimatorSet anim = new AnimatorSet();
- AnimatorSet.Builder b = anim.play(
- ObjectAnimator.ofFloat(mContainerView, "translationY", -mContainerView.getHeight()))
- .with(ObjectAnimator.ofFloat(mContainerView, "alpha", 0));
+ AnimatorSet.Builder b = anim.play(ObjectAnimator.ofFloat(mContainerView, "alpha", 0));
if (mContentView != null) {
- b.with(ObjectAnimator.ofFloat(mContentView, "translationY", 0, -mContainerView.getHeight()));
+ b.with(ObjectAnimator.ofFloat(mContentView, "translationY",
+ 0, -mContainerView.getHeight()));
+ b.with(ObjectAnimator.ofFloat(mContainerView, "translationY",
+ -mContainerView.getHeight()));
}
anim.addListener(mHideListener);
mCurrentAnim = anim;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 92b50c7..981661a 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1335,6 +1335,11 @@
android:exported="true">
</activity>
+ <activity android:name="android.content.SyncActivityTooManyDeletes"
+ android:theme="@android:style/Theme.Holo.Dialog"
+ android:label="@string/sync_too_many_deletes">
+ </activity>
+
<activity android:name="com.android.server.ShutdownActivity"
android:permission="android.permission.SHUTDOWN"
android:excludeFromRecents="true">
diff --git a/core/res/res/drawable-hdpi/day_picker_week_view_dayline_holo_dark.9.png b/core/res/res/drawable-hdpi/day_picker_week_view_dayline_holo.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/day_picker_week_view_dayline_holo_dark.9.png
rename to core/res/res/drawable-hdpi/day_picker_week_view_dayline_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/day_picker_week_view_dayline_holo_light.9.png b/core/res/res/drawable-hdpi/day_picker_week_view_dayline_holo_light.9.png
deleted file mode 100644
index 2edae8f..0000000
--- a/core/res/res/drawable-hdpi/day_picker_week_view_dayline_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_down_disabled_focused_holo_dark.png b/core/res/res/drawable-hdpi/timepicker_down_disabled_focused_holo_dark.png
index 6fbd7d2..f43f9ad 100644
--- a/core/res/res/drawable-hdpi/timepicker_down_disabled_focused_holo_dark.png
+++ b/core/res/res/drawable-hdpi/timepicker_down_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_down_disabled_focused_holo_light.png b/core/res/res/drawable-hdpi/timepicker_down_disabled_focused_holo_light.png
index 3a4cdec..2ada3ef 100644
--- a/core/res/res/drawable-hdpi/timepicker_down_disabled_focused_holo_light.png
+++ b/core/res/res/drawable-hdpi/timepicker_down_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_down_disabled_holo_dark.png b/core/res/res/drawable-hdpi/timepicker_down_disabled_holo_dark.png
index b1c3991..5ed7040 100644
--- a/core/res/res/drawable-hdpi/timepicker_down_disabled_holo_dark.png
+++ b/core/res/res/drawable-hdpi/timepicker_down_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_down_disabled_holo_light.png b/core/res/res/drawable-hdpi/timepicker_down_disabled_holo_light.png
index 6fbce8c..d4a01cf 100644
--- a/core/res/res/drawable-hdpi/timepicker_down_disabled_holo_light.png
+++ b/core/res/res/drawable-hdpi/timepicker_down_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_down_focused_holo_dark.png b/core/res/res/drawable-hdpi/timepicker_down_focused_holo_dark.png
index 3bb4c29..ada6251 100644
--- a/core/res/res/drawable-hdpi/timepicker_down_focused_holo_dark.png
+++ b/core/res/res/drawable-hdpi/timepicker_down_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_down_focused_holo_light.png b/core/res/res/drawable-hdpi/timepicker_down_focused_holo_light.png
index 8f02162..1247c7a 100644
--- a/core/res/res/drawable-hdpi/timepicker_down_focused_holo_light.png
+++ b/core/res/res/drawable-hdpi/timepicker_down_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_down_longpressed_holo_dark.png b/core/res/res/drawable-hdpi/timepicker_down_longpressed_holo_dark.png
index 8f57d2c..3d13454 100644
--- a/core/res/res/drawable-hdpi/timepicker_down_longpressed_holo_dark.png
+++ b/core/res/res/drawable-hdpi/timepicker_down_longpressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_down_longpressed_holo_light.png b/core/res/res/drawable-hdpi/timepicker_down_longpressed_holo_light.png
index df6f76b..4898244 100644
--- a/core/res/res/drawable-hdpi/timepicker_down_longpressed_holo_light.png
+++ b/core/res/res/drawable-hdpi/timepicker_down_longpressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_down_normal_holo_dark.png b/core/res/res/drawable-hdpi/timepicker_down_normal_holo_dark.png
index a47bf31..bb1074c 100644
--- a/core/res/res/drawable-hdpi/timepicker_down_normal_holo_dark.png
+++ b/core/res/res/drawable-hdpi/timepicker_down_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_down_normal_holo_light.png b/core/res/res/drawable-hdpi/timepicker_down_normal_holo_light.png
index 04046aa..e6e5a0f 100644
--- a/core/res/res/drawable-hdpi/timepicker_down_normal_holo_light.png
+++ b/core/res/res/drawable-hdpi/timepicker_down_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_down_pressed_holo_dark.png b/core/res/res/drawable-hdpi/timepicker_down_pressed_holo_dark.png
index b6021e0..b54e603 100644
--- a/core/res/res/drawable-hdpi/timepicker_down_pressed_holo_dark.png
+++ b/core/res/res/drawable-hdpi/timepicker_down_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_down_pressed_holo_light.png b/core/res/res/drawable-hdpi/timepicker_down_pressed_holo_light.png
index 0f38d6b..70ee54c 100644
--- a/core/res/res/drawable-hdpi/timepicker_down_pressed_holo_light.png
+++ b/core/res/res/drawable-hdpi/timepicker_down_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_up_disabled_focused_holo_dark.png b/core/res/res/drawable-hdpi/timepicker_up_disabled_focused_holo_dark.png
index 14a4e31..a55c96a 100644
--- a/core/res/res/drawable-hdpi/timepicker_up_disabled_focused_holo_dark.png
+++ b/core/res/res/drawable-hdpi/timepicker_up_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_up_disabled_focused_holo_light.png b/core/res/res/drawable-hdpi/timepicker_up_disabled_focused_holo_light.png
index 21a2ac1..4e31c72 100644
--- a/core/res/res/drawable-hdpi/timepicker_up_disabled_focused_holo_light.png
+++ b/core/res/res/drawable-hdpi/timepicker_up_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_up_disabled_holo_dark.png b/core/res/res/drawable-hdpi/timepicker_up_disabled_holo_dark.png
index 1a1da57..8158596 100644
--- a/core/res/res/drawable-hdpi/timepicker_up_disabled_holo_dark.png
+++ b/core/res/res/drawable-hdpi/timepicker_up_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_up_disabled_holo_light.png b/core/res/res/drawable-hdpi/timepicker_up_disabled_holo_light.png
index a242c80..37e5c0d 100644
--- a/core/res/res/drawable-hdpi/timepicker_up_disabled_holo_light.png
+++ b/core/res/res/drawable-hdpi/timepicker_up_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_up_focused_holo_dark.png b/core/res/res/drawable-hdpi/timepicker_up_focused_holo_dark.png
index 50045e4..7ec94e6 100644
--- a/core/res/res/drawable-hdpi/timepicker_up_focused_holo_dark.png
+++ b/core/res/res/drawable-hdpi/timepicker_up_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_up_focused_holo_light.png b/core/res/res/drawable-hdpi/timepicker_up_focused_holo_light.png
index 659b3c7..780fff1 100644
--- a/core/res/res/drawable-hdpi/timepicker_up_focused_holo_light.png
+++ b/core/res/res/drawable-hdpi/timepicker_up_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_up_longpressed_holo_dark.png b/core/res/res/drawable-hdpi/timepicker_up_longpressed_holo_dark.png
index 9112530..73c8dd9 100644
--- a/core/res/res/drawable-hdpi/timepicker_up_longpressed_holo_dark.png
+++ b/core/res/res/drawable-hdpi/timepicker_up_longpressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_up_longpressed_holo_light.png b/core/res/res/drawable-hdpi/timepicker_up_longpressed_holo_light.png
index 21aa7f7..3b96480 100644
--- a/core/res/res/drawable-hdpi/timepicker_up_longpressed_holo_light.png
+++ b/core/res/res/drawable-hdpi/timepicker_up_longpressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_up_normal_holo_dark.png b/core/res/res/drawable-hdpi/timepicker_up_normal_holo_dark.png
index d145975..21f0871 100644
--- a/core/res/res/drawable-hdpi/timepicker_up_normal_holo_dark.png
+++ b/core/res/res/drawable-hdpi/timepicker_up_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_up_normal_holo_light.png b/core/res/res/drawable-hdpi/timepicker_up_normal_holo_light.png
index 167bab7..49e3c15 100644
--- a/core/res/res/drawable-hdpi/timepicker_up_normal_holo_light.png
+++ b/core/res/res/drawable-hdpi/timepicker_up_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_up_pressed_holo_dark.png b/core/res/res/drawable-hdpi/timepicker_up_pressed_holo_dark.png
index 2844c3f..a15a5f5 100644
--- a/core/res/res/drawable-hdpi/timepicker_up_pressed_holo_dark.png
+++ b/core/res/res/drawable-hdpi/timepicker_up_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/timepicker_up_pressed_holo_light.png b/core/res/res/drawable-hdpi/timepicker_up_pressed_holo_light.png
index 9d83038..7441361 100644
--- a/core/res/res/drawable-hdpi/timepicker_up_pressed_holo_light.png
+++ b/core/res/res/drawable-hdpi/timepicker_up_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/day_picker_week_view_dayline_holo_dark.9.png b/core/res/res/drawable-mdpi/day_picker_week_view_dayline_holo.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/day_picker_week_view_dayline_holo_dark.9.png
rename to core/res/res/drawable-mdpi/day_picker_week_view_dayline_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/day_picker_week_view_dayline_holo_light.9.png b/core/res/res/drawable-mdpi/day_picker_week_view_dayline_holo_light.9.png
deleted file mode 100644
index a8cfd77..0000000
--- a/core/res/res/drawable-mdpi/day_picker_week_view_dayline_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_down_disabled_focused_holo_dark.png b/core/res/res/drawable-mdpi/timepicker_down_disabled_focused_holo_dark.png
index d86534c..113b369 100644
--- a/core/res/res/drawable-mdpi/timepicker_down_disabled_focused_holo_dark.png
+++ b/core/res/res/drawable-mdpi/timepicker_down_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_down_disabled_focused_holo_light.png b/core/res/res/drawable-mdpi/timepicker_down_disabled_focused_holo_light.png
index 6ae5d4b..e3c416e 100644
--- a/core/res/res/drawable-mdpi/timepicker_down_disabled_focused_holo_light.png
+++ b/core/res/res/drawable-mdpi/timepicker_down_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_down_disabled_holo_dark.png b/core/res/res/drawable-mdpi/timepicker_down_disabled_holo_dark.png
index fd578b6..e123db9 100644
--- a/core/res/res/drawable-mdpi/timepicker_down_disabled_holo_dark.png
+++ b/core/res/res/drawable-mdpi/timepicker_down_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_down_disabled_holo_light.png b/core/res/res/drawable-mdpi/timepicker_down_disabled_holo_light.png
index a0caaa9..f93d082 100644
--- a/core/res/res/drawable-mdpi/timepicker_down_disabled_holo_light.png
+++ b/core/res/res/drawable-mdpi/timepicker_down_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_down_focused_holo_dark.png b/core/res/res/drawable-mdpi/timepicker_down_focused_holo_dark.png
index f6f4ed2..d8bd34f 100644
--- a/core/res/res/drawable-mdpi/timepicker_down_focused_holo_dark.png
+++ b/core/res/res/drawable-mdpi/timepicker_down_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_down_focused_holo_light.png b/core/res/res/drawable-mdpi/timepicker_down_focused_holo_light.png
index 2591adb..0747f82 100644
--- a/core/res/res/drawable-mdpi/timepicker_down_focused_holo_light.png
+++ b/core/res/res/drawable-mdpi/timepicker_down_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_down_longpressed_holo_dark.png b/core/res/res/drawable-mdpi/timepicker_down_longpressed_holo_dark.png
index efee099..1c7abf8 100644
--- a/core/res/res/drawable-mdpi/timepicker_down_longpressed_holo_dark.png
+++ b/core/res/res/drawable-mdpi/timepicker_down_longpressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_down_longpressed_holo_light.png b/core/res/res/drawable-mdpi/timepicker_down_longpressed_holo_light.png
index f7b09de..ec9d1f2 100644
--- a/core/res/res/drawable-mdpi/timepicker_down_longpressed_holo_light.png
+++ b/core/res/res/drawable-mdpi/timepicker_down_longpressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_down_normal_holo_dark.png b/core/res/res/drawable-mdpi/timepicker_down_normal_holo_dark.png
index 76f13a6..d6259e2 100644
--- a/core/res/res/drawable-mdpi/timepicker_down_normal_holo_dark.png
+++ b/core/res/res/drawable-mdpi/timepicker_down_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_down_normal_holo_light.png b/core/res/res/drawable-mdpi/timepicker_down_normal_holo_light.png
index cb8e764..aac5f31 100644
--- a/core/res/res/drawable-mdpi/timepicker_down_normal_holo_light.png
+++ b/core/res/res/drawable-mdpi/timepicker_down_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_down_pressed_holo_dark.png b/core/res/res/drawable-mdpi/timepicker_down_pressed_holo_dark.png
index 7c0d0bc..fd8076f 100644
--- a/core/res/res/drawable-mdpi/timepicker_down_pressed_holo_dark.png
+++ b/core/res/res/drawable-mdpi/timepicker_down_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_down_pressed_holo_light.png b/core/res/res/drawable-mdpi/timepicker_down_pressed_holo_light.png
index 9d7ff6b..c06ff40 100644
--- a/core/res/res/drawable-mdpi/timepicker_down_pressed_holo_light.png
+++ b/core/res/res/drawable-mdpi/timepicker_down_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_up_disabled_focused_holo_dark.png b/core/res/res/drawable-mdpi/timepicker_up_disabled_focused_holo_dark.png
index cfdfd174..d69615d 100644
--- a/core/res/res/drawable-mdpi/timepicker_up_disabled_focused_holo_dark.png
+++ b/core/res/res/drawable-mdpi/timepicker_up_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_up_disabled_focused_holo_light.png b/core/res/res/drawable-mdpi/timepicker_up_disabled_focused_holo_light.png
index 43bdf1d..eb7a283 100644
--- a/core/res/res/drawable-mdpi/timepicker_up_disabled_focused_holo_light.png
+++ b/core/res/res/drawable-mdpi/timepicker_up_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_up_disabled_holo_dark.png b/core/res/res/drawable-mdpi/timepicker_up_disabled_holo_dark.png
index 2ffe46b..1ee5510 100644
--- a/core/res/res/drawable-mdpi/timepicker_up_disabled_holo_dark.png
+++ b/core/res/res/drawable-mdpi/timepicker_up_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_up_disabled_holo_light.png b/core/res/res/drawable-mdpi/timepicker_up_disabled_holo_light.png
index 51bb2d0..2269577 100644
--- a/core/res/res/drawable-mdpi/timepicker_up_disabled_holo_light.png
+++ b/core/res/res/drawable-mdpi/timepicker_up_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_up_focused_holo_dark.png b/core/res/res/drawable-mdpi/timepicker_up_focused_holo_dark.png
index dece157..9954130 100644
--- a/core/res/res/drawable-mdpi/timepicker_up_focused_holo_dark.png
+++ b/core/res/res/drawable-mdpi/timepicker_up_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_up_focused_holo_light.png b/core/res/res/drawable-mdpi/timepicker_up_focused_holo_light.png
index 384cb32..8553d1c 100644
--- a/core/res/res/drawable-mdpi/timepicker_up_focused_holo_light.png
+++ b/core/res/res/drawable-mdpi/timepicker_up_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_up_longpressed_holo_dark.png b/core/res/res/drawable-mdpi/timepicker_up_longpressed_holo_dark.png
index 84ec4f7..b4ed2c5 100644
--- a/core/res/res/drawable-mdpi/timepicker_up_longpressed_holo_dark.png
+++ b/core/res/res/drawable-mdpi/timepicker_up_longpressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_up_longpressed_holo_light.png b/core/res/res/drawable-mdpi/timepicker_up_longpressed_holo_light.png
index 318befc..2496fb8 100644
--- a/core/res/res/drawable-mdpi/timepicker_up_longpressed_holo_light.png
+++ b/core/res/res/drawable-mdpi/timepicker_up_longpressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_up_normal_holo_dark.png b/core/res/res/drawable-mdpi/timepicker_up_normal_holo_dark.png
index d97a832..3bcdd71 100644
--- a/core/res/res/drawable-mdpi/timepicker_up_normal_holo_dark.png
+++ b/core/res/res/drawable-mdpi/timepicker_up_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_up_normal_holo_light.png b/core/res/res/drawable-mdpi/timepicker_up_normal_holo_light.png
index 19d75e5..1113de7 100644
--- a/core/res/res/drawable-mdpi/timepicker_up_normal_holo_light.png
+++ b/core/res/res/drawable-mdpi/timepicker_up_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_up_pressed_holo_dark.png b/core/res/res/drawable-mdpi/timepicker_up_pressed_holo_dark.png
index 1189e5c..7303a19 100644
--- a/core/res/res/drawable-mdpi/timepicker_up_pressed_holo_dark.png
+++ b/core/res/res/drawable-mdpi/timepicker_up_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/timepicker_up_pressed_holo_light.png b/core/res/res/drawable-mdpi/timepicker_up_pressed_holo_light.png
index 9f283ab..7abdbfc 100644
--- a/core/res/res/drawable-mdpi/timepicker_up_pressed_holo_light.png
+++ b/core/res/res/drawable-mdpi/timepicker_up_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/layout/preference_list_content.xml b/core/res/res/layout/preference_list_content.xml
index e7783da..a5f87d3 100644
--- a/core/res/res/layout/preference_list_content.xml
+++ b/core/res/res/layout/preference_list_content.xml
@@ -34,7 +34,7 @@
android:orientation="vertical"
android:layout_width="0px"
android:layout_height="match_parent"
- android:layout_marginRight="0dp"
+ android:layout_marginRight="@dimen/preference_screen_side_margin_negative"
android:layout_marginLeft="@dimen/preference_screen_side_margin"
android:layout_marginTop="32dp"
android:layout_marginBottom="32dp"
@@ -61,7 +61,7 @@
android:layout_width="0px"
android:layout_height="match_parent"
android:layout_weight="20"
- android:layout_marginLeft="-4dp"
+ android:layout_marginLeft="@dimen/preference_screen_side_margin"
android:layout_marginRight="@dimen/preference_screen_side_margin"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
diff --git a/core/res/res/values-land/dimens.xml b/core/res/res/values-land/dimens.xml
index b1f12b5..fbfc3bf 100644
--- a/core/res/res/values-land/dimens.xml
+++ b/core/res/res/values-land/dimens.xml
@@ -22,5 +22,6 @@
<dimen name="password_keyboard_key_height">47dip</dimen>
<dimen name="password_keyboard_spacebar_vertical_correction">2dip</dimen>
<dimen name="preference_screen_side_margin">96dp</dimen>
+ <dimen name="preference_screen_side_margin_negative">-100dp</dimen>
<dimen name="preference_widget_width">72dp</dimen>
-</resources>
\ No newline at end of file
+</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 98c9270..873f539 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -48,6 +48,7 @@
theme does not set this value, meaning it is based on whether the
window is floating. -->
<attr name="backgroundDimEnabled" format="boolean" />
+
<!-- =========== -->
<!-- Text styles -->
<!-- =========== -->
@@ -261,7 +262,7 @@
<!-- Flag indicating whether this is a translucent window. -->
<attr name="windowIsTranslucent" format="boolean" />
<!-- Flag indicating that this window's background should be the
- user's current wallpaper. -->
+ user's current wallpaper. -->
<attr name="windowShowWallpaper" format="boolean" />
<!-- This Drawable is overlaid over the foreground of the Window's content area, usually
to place a shadow below the title. -->
@@ -4310,7 +4311,7 @@
If not supplied, then no activity will be launched. -->
<attr name="configure" format="string" />
<!-- A preview of what the AppWidget will look like after it's configured.
- If not supplied, the AppWidget's icon will be used. -->
+ If not supplied, the AppWidget's icon will be used. -->
<attr name="previewImage" format="reference" />
<!-- The view id of the AppWidget subview which should be auto-advanced.
by the widget's host. -->
@@ -4421,6 +4422,10 @@
<attr name="smallIcon" format="reference"/>
<!-- A preferences.xml file for authenticator-specific settings. -->
<attr name="accountPreferences" format="reference"/>
+ <!-- Account handles its own token storage and permissions.
+ Default to false
+ -->
+ <attr name="customTokens" format="boolean"/>
</declare-styleable>
<!-- =============================== -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 5d03638..0d2d42f 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -497,6 +497,17 @@
to handle queries on each database. -->
<integer name="db_connection_pool_size">1</integer>
+ <!-- Max space (in MB) allocated to DownloadManager to store the downloaded
+ files if they are to be stored in DownloadManager's data dir,
+ which typically is /data/data/com.android.providers.downloads/files -->
+ <integer name="config_downloadDataDirSize">100</integer>
+
+ <!-- When the free space available in DownloadManager's data dir falls
+ below the percentage value specified by this param, DownloadManager
+ starts removing files to try to make percentage of available
+ free space above this threshold value. -->
+ <integer name="config_downloadDataDirLowSpaceThreshold">10</integer>
+
<!-- The URL that should be sent in an x-wap-profile header with an HTTP request,
as defined in the Open Mobile Alliance User Agent Profile specification
OMA-TS-UAProf-V2_0-20060206-A Section 8.1.1.1. If the URL contains a '%s'
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 2f0dfc1..53d4e42 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -54,6 +54,8 @@
<dimen name="password_keyboard_spacebar_vertical_correction">4dip</dimen>
<!-- Preference activity side margins -->
<dimen name="preference_screen_side_margin">0dp</dimen>
+ <!-- Preference activity side margins negative-->
+ <dimen name="preference_screen_side_margin_negative">0dp</dimen>
<!-- Preference widget area width (to the left of the text) -->
<dimen name="preference_widget_width">56dp</dimen>
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 3a5b238..7e06c86 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1407,6 +1407,7 @@
<public type="attr" name="fastScrollPreviewBackgroundRight" />
<public type="attr" name="fastScrollTrackDrawable" />
<public type="attr" name="fastScrollOverlayPosition" />
+ <public type="attr" name="customTokens" />
<public type="anim" name="animator_fade_in" />
<public type="anim" name="animator_fade_out" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index e48321c..92f3593 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -298,12 +298,12 @@
<string name="shutdown_confirm_question">Would you like to shut down?</string>
<!-- Recent Tasks dialog: title
- TODO: this should move to SystemUI.apk, but the code for the old
+ TODO: this should move to SystemUI.apk, but the code for the old
recent dialog is still in the framework
-->
<string name="recent_tasks_title">Recent</string>
<!-- Recent Tasks dialog: message when there are no recent applications
- TODO: this should move to SystemUI.apk, but the code for the old
+ TODO: this should move to SystemUI.apk, but the code for the old
recent dialog is still in the framework
-->
<string name="no_recent_tasks">No recent applications.</string>
@@ -1363,17 +1363,17 @@
<!-- Title of policy access to limiting the user's password choices -->
<string name="policylab_limitPassword">Set password rules</string>
<!-- Description of policy access to limiting the user's password choices -->
- <string name="policydesc_limitPassword">Control the length and the characters
+ <string name="policydesc_limitPassword">Control the length and the characters
allowed in screen-unlock passwords</string>
<!-- Title of policy access to watch user login attempts -->
<string name="policylab_watchLogin">Monitor screen-unlock attempts</string>
<!-- Description of policy access to watch user login attempts -->
- <string name="policydesc_watchLogin" product="tablet">Monitor the number of incorrect passwords
- entered when unlocking the screen, and lock the tablet or erase all the tablet\'s
+ <string name="policydesc_watchLogin" product="tablet">Monitor the number of incorrect passwords
+ entered when unlocking the screen, and lock the tablet or erase all the tablet\'s
data if too many incorrect passwords are entered</string>
<!-- Description of policy access to watch user login attempts -->
- <string name="policydesc_watchLogin" product="default">Monitor the number of incorrect passwords
- entered when unlocking the screen, and lock the phone or erase all the phone\'s
+ <string name="policydesc_watchLogin" product="default">Monitor the number of incorrect passwords
+ entered when unlocking the screen, and lock the phone or erase all the phone\'s
data if too many incorrect passwords are entered</string>
<!-- Title of policy access to reset user's password -->
<string name="policylab_resetPassword">Change the screen-unlock password</string>
@@ -1386,10 +1386,10 @@
<!-- Title of policy access to wipe the user's data -->
<string name="policylab_wipeData">Erase all data</string>
<!-- Description of policy access to wipe the user's data -->
- <string name="policydesc_wipeData" product="tablet">Erase the tablet\'s data without warning,
+ <string name="policydesc_wipeData" product="tablet">Erase the tablet\'s data without warning,
by performing a factory data reset</string>
<!-- Description of policy access to wipe the user's data -->
- <string name="policydesc_wipeData" product="default">Erase the phone\'s data without warning,
+ <string name="policydesc_wipeData" product="default">Erase the phone\'s data without warning,
by performing a factory data reset</string>
<string name="policylab_setGlobalProxy">Set the device global proxy</string>
<!-- Description of policy access to wipe the user's data -->
@@ -1602,7 +1602,7 @@
<string name="relationTypeSister">Sister</string>
<!-- Spouse relationship type [CHAR LIMIT=20] -->
<string name="relationTypeSpouse">Spouse</string>
-
+
<!-- Custom SIP address type -->
<string name="sipAddressTypeCustom">Custom</string>
<!-- Home SIP address type -->
@@ -2640,4 +2640,15 @@
<!-- Network positioning verification No. Button to push to deny sharing of location
information. -->
<string name="gpsVerifNo">No</string>
+
+ <!-- Error message when the sync tried to delete too many things -->
+ <string name="sync_too_many_deletes">Delete limit exceeded</string>
+ <!-- Dialog message for when there are too many deletes that would take place and we want user confirmation -->
+ <string name="sync_too_many_deletes_desc">There are <xliff:g id="number_of_deleted_items">%1$d</xliff:g> deleted items for <xliff:g id="type_of_sync">%2$s</xliff:g>, account <xliff:g id="account_name">%3$s</xliff:g>. What would you like to do?</string>
+ <!-- Dialog action for when there are too many deletes that would take place and we want user confirmation, and the user wants to delete the items -->
+ <string name="sync_really_delete">Delete the items.</string>
+ <!-- Dialog action for when there are too many deletes that would take place and we want user confirmation, and the user wants to undo the deletions -->
+ <string name="sync_undo_deletes">Undo the deletes.</string>
+ <!-- Dialog action for when there are too many deletes that would take place and we want user confirmation, and the user wants to do nothing for now -->
+ <string name="sync_do_nothing">Do nothing for now.</string>
</resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 3e75261..920a59e 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -488,7 +488,7 @@
<item name="android:otherMonthDateColor">#66FFFFFF</item>
<item name="android:weekNumberColor">#33FFFFFF</item>
<item name="android:gridLinesColor">#19FFFFFF</item>
- <item name="selectedDayLine">@android:drawable/day_picker_week_view_dayline_holo_dark</item>
+ <item name="selectedDayLine">@android:drawable/day_picker_week_view_dayline_holo</item>
</style>
<!-- @hide -->
@@ -1450,7 +1450,7 @@
<item name="android:otherMonthDateColor">#66FFFFFF</item>
<item name="android:weekNumberColor">#33FFFFFF</item>
<item name="android:gridLinesColor">#19FFFFFF</item>
- <item name="selectedDayLine">@android:drawable/day_picker_week_view_dayline_holo_dark</item>
+ <item name="selectedDayLine">@android:drawable/day_picker_week_view_dayline_holo</item>
</style>
<style name="Widget.Holo.ImageButton" parent="Widget.ImageButton">
@@ -1819,12 +1819,12 @@
<!-- @hide -->
<style name="Widget.Holo.Light.DayPickerWeekView" parent="Widget.DayPickerWeekView">
- <item name="android:selectionBackgroundColor">#7F080030</item>
+ <item name="android:selectionBackgroundColor">#330066ff</item>
<item name="android:focusedMonthDateColor">#FF000000</item>
<item name="android:otherMonthDateColor">#7F08002B</item>
<item name="android:weekNumberColor">#7F080021</item>
<item name="android:gridLinesColor">#7F08002A</item>
- <item name="selectedDayLine">@android:drawable/day_picker_week_view_dayline_holo_light</item>
+ <item name="selectedDayLine">@android:drawable/day_picker_week_view_dayline_holo</item>
</style>
<!-- @hide -->
diff --git a/graphics/java/android/renderscript/FieldPacker.java b/graphics/java/android/renderscript/FieldPacker.java
index ff3e22b..ed16451 100644
--- a/graphics/java/android/renderscript/FieldPacker.java
+++ b/graphics/java/android/renderscript/FieldPacker.java
@@ -248,24 +248,45 @@
addU32(v.w);
}
+ // to be removed on cleanup
public void addObj(Matrix4f v) {
for (int i=0; i < v.mMat.length; i++) {
addF32(v.mMat[i]);
}
}
+ // to be removed on cleanup
public void addObj(Matrix3f v) {
for (int i=0; i < v.mMat.length; i++) {
addF32(v.mMat[i]);
}
}
+ // to be removed on cleanup
public void addObj(Matrix2f v) {
for (int i=0; i < v.mMat.length; i++) {
addF32(v.mMat[i]);
}
}
+ public void addMatrix(Matrix4f v) {
+ for (int i=0; i < v.mMat.length; i++) {
+ addF32(v.mMat[i]);
+ }
+ }
+
+ public void addMatrix(Matrix3f v) {
+ for (int i=0; i < v.mMat.length; i++) {
+ addF32(v.mMat[i]);
+ }
+ }
+
+ public void addMatrix(Matrix2f v) {
+ for (int i=0; i < v.mMat.length; i++) {
+ addF32(v.mMat[i]);
+ }
+ }
+
public void addBoolean(boolean v) {
addI8((byte)(v ? 1 : 0));
}
diff --git a/graphics/java/android/renderscript/FileA3D.java b/graphics/java/android/renderscript/FileA3D.java
index af85d8e..c3e5faf 100644
--- a/graphics/java/android/renderscript/FileA3D.java
+++ b/graphics/java/android/renderscript/FileA3D.java
@@ -16,11 +16,12 @@
package android.renderscript;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
-import android.content.res.Resources;
import android.content.res.AssetManager;
+import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
@@ -32,28 +33,33 @@
**/
public class FileA3D extends BaseObj {
+ // This will go away in the clean up pass,
+ // trying to avoid multiproject submits
public enum ClassID {
UNKNOWN,
- MESH,
- TYPE,
- ELEMENT,
- ALLOCATION,
- PROGRAM_VERTEX,
- PROGRAM_RASTER,
- PROGRAM_FRAGMENT,
- PROGRAM_STORE,
- SAMPLER,
- ANIMATION,
- ADAPTER_1D,
- ADAPTER_2D,
- SCRIPT_C;
+ MESH;
public static ClassID toClassID(int intID) {
return ClassID.values()[intID];
}
}
+ public enum EntryType {
+
+ UNKNOWN (0),
+ MESH (1);
+
+ int mID;
+ EntryType(int id) {
+ mID = id;
+ }
+
+ static EntryType toEntryType(int intID) {
+ return EntryType.values()[intID];
+ }
+ }
+
// Read only class with index entries
public static class IndexEntry {
RenderScript mRS;
@@ -61,6 +67,7 @@
int mID;
String mName;
ClassID mClassID;
+ EntryType mEntryType;
BaseObj mLoadedObj;
public String getName() {
@@ -71,18 +78,27 @@
return mClassID;
}
+ public EntryType getEntryType() {
+ return mEntryType;
+ }
+
public BaseObj getObject() {
mRS.validate();
BaseObj obj = internalCreate(mRS, this);
return obj;
}
+ public Mesh getMesh() {
+ return (Mesh)getObject();
+ }
+
static synchronized BaseObj internalCreate(RenderScript rs, IndexEntry entry) {
if(entry.mLoadedObj != null) {
return entry.mLoadedObj;
}
- if(entry.mClassID == ClassID.UNKNOWN) {
+ // to be purged on cleanup
+ if(entry.mEntryType == EntryType.UNKNOWN) {
return null;
}
@@ -91,51 +107,23 @@
return null;
}
- switch (entry.mClassID) {
+ switch (entry.mEntryType) {
case MESH:
entry.mLoadedObj = new Mesh(objectID, rs);
break;
- case TYPE:
- entry.mLoadedObj = new Type(objectID, rs);
- break;
- case ELEMENT:
- entry.mLoadedObj = null;
- break;
- case ALLOCATION:
- entry.mLoadedObj = null;
- break;
- case PROGRAM_VERTEX:
- entry.mLoadedObj = new ProgramVertex(objectID, rs);
- break;
- case PROGRAM_RASTER:
- break;
- case PROGRAM_FRAGMENT:
- break;
- case PROGRAM_STORE:
- break;
- case SAMPLER:
- break;
- case ANIMATION:
- break;
- case ADAPTER_1D:
- break;
- case ADAPTER_2D:
- break;
- case SCRIPT_C:
- break;
}
entry.mLoadedObj.updateFromNative();
-
return entry.mLoadedObj;
}
- IndexEntry(RenderScript rs, int index, int id, String name, ClassID classID) {
+ IndexEntry(RenderScript rs, int index, int id, String name, EntryType type) {
mRS = rs;
mIndex = index;
mID = id;
mName = name;
- mClassID = classID;
+ mEntryType = type;
+ mClassID = mEntryType == EntryType.MESH ? ClassID.MESH : ClassID.UNKNOWN;
mLoadedObj = null;
}
}
@@ -161,11 +149,11 @@
mRS.nFileA3DGetIndexEntries(getID(), numFileEntries, ids, names);
for(int i = 0; i < numFileEntries; i ++) {
- mFileEntries[i] = new IndexEntry(mRS, i, getID(), names[i], ClassID.toClassID(ids[i]));
+ mFileEntries[i] = new IndexEntry(mRS, i, getID(), names[i], EntryType.toEntryType(ids[i]));
}
}
- public int getNumIndexEntries() {
+ public int getIndexEntryCount() {
if(mFileEntries == null) {
return 0;
}
@@ -173,12 +161,29 @@
}
public IndexEntry getIndexEntry(int index) {
- if(getNumIndexEntries() == 0 || index < 0 || index >= mFileEntries.length) {
+ if(getIndexEntryCount() == 0 || index < 0 || index >= mFileEntries.length) {
return null;
}
return mFileEntries[index];
}
+ // API cleanup stand-ins
+ // TODO: implement ermaining loading mechanisms
+ static public FileA3D createFromAsset(RenderScript rs, AssetManager mgr, String path)
+ throws IllegalArgumentException {
+ return null;
+ }
+
+ static public FileA3D createFromFile(RenderScript rs, String path)
+ throws IllegalArgumentException {
+ return null;
+ }
+
+ static public FileA3D createFromFile(RenderScript rs, File path)
+ throws IllegalArgumentException {
+ return createFromFile(rs, path.getAbsolutePath());
+ }
+
static public FileA3D createFromResource(RenderScript rs, Resources res, int id)
throws IllegalArgumentException {
diff --git a/graphics/java/android/renderscript/Font.java b/graphics/java/android/renderscript/Font.java
index de25014..0f7c24d 100644
--- a/graphics/java/android/renderscript/Font.java
+++ b/graphics/java/android/renderscript/Font.java
@@ -16,13 +16,16 @@
package android.renderscript;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
-import java.util.Map;
import java.util.HashMap;
+import java.util.Map;
-import android.content.res.Resources;
+import android.os.Environment;
+
import android.content.res.AssetManager;
+import android.content.res.Resources;
import android.util.Log;
import android.util.TypedValue;
@@ -126,13 +129,13 @@
/**
* Takes a specific file name as an argument
*/
- static public Font create(RenderScript rs, Resources res, String fileName, int size)
+ static public Font createFromFile(RenderScript rs, Resources res, String path, float pointSize)
throws IllegalArgumentException {
rs.validate();
try {
int dpi = res.getDisplayMetrics().densityDpi;
- int fontId = rs.nFontCreateFromFile(fileName, size, dpi);
+ int fontId = rs.nFontCreateFromFile(path, pointSize, dpi);
if(fontId == 0) {
throw new IllegalStateException("Failed loading a font");
@@ -148,6 +151,21 @@
return null;
}
+ static public Font createFromFile(RenderScript rs, Resources res, File path, float pointSize)
+ throws IllegalArgumentException {
+ return createFromFile(rs, res, path.getAbsolutePath(), pointSize);
+ }
+
+ static public Font createFromAsset(RenderScript rs, Resources res, AssetManager mgr, String path, float pointSize)
+ throws IllegalArgumentException {
+ return null;
+ }
+
+ static public Font createFromResource(RenderScript rs, Resources res, int id, float pointSize)
+ throws IllegalArgumentException {
+ return null;
+ }
+
/**
* Accepts one of the following family names as an argument
* and will attemp to produce the best match with a system font
@@ -157,9 +175,12 @@
* "monospace" "courier" "courier new" "monaco"
* Returns default font if no match could be found
*/
- static public Font createFromFamily(RenderScript rs, Resources res, String familyName, Style fontStyle, int size)
+ static public Font create(RenderScript rs, Resources res, String familyName, Style fontStyle, float pointSize)
throws IllegalArgumentException {
String fileName = getFontFileName(familyName, fontStyle);
- return create(rs, res, fileName, size);
+ String fontPath = Environment.getRootDirectory().getAbsolutePath();
+ fontPath += "/fonts/" + fileName;
+ return createFromFile(rs, res, fontPath, pointSize);
}
+
}
diff --git a/graphics/java/android/renderscript/Matrix2f.java b/graphics/java/android/renderscript/Matrix2f.java
index 99d23db..4654c48 100644
--- a/graphics/java/android/renderscript/Matrix2f.java
+++ b/graphics/java/android/renderscript/Matrix2f.java
@@ -31,6 +31,15 @@
loadIdentity();
}
+ public Matrix2f(float[] dataArray) {
+ mMat = new float[2];
+ System.arraycopy(dataArray, 0, mMat, 0, mMat.length);
+ }
+
+ public float[] getArray() {
+ return mMat;
+ }
+
public float get(int i, int j) {
return mMat[i*2 + j];
}
diff --git a/graphics/java/android/renderscript/Matrix3f.java b/graphics/java/android/renderscript/Matrix3f.java
index 961bc5d..15e5ce6 100644
--- a/graphics/java/android/renderscript/Matrix3f.java
+++ b/graphics/java/android/renderscript/Matrix3f.java
@@ -31,6 +31,15 @@
loadIdentity();
}
+ public Matrix3f(float[] dataArray) {
+ mMat = new float[9];
+ System.arraycopy(dataArray, 0, mMat, 0, mMat.length);
+ }
+
+ public float[] getArray() {
+ return mMat;
+ }
+
public float get(int i, int j) {
return mMat[i*3 + j];
}
diff --git a/graphics/java/android/renderscript/Matrix4f.java b/graphics/java/android/renderscript/Matrix4f.java
index 5ffc21a..ea97509 100644
--- a/graphics/java/android/renderscript/Matrix4f.java
+++ b/graphics/java/android/renderscript/Matrix4f.java
@@ -31,6 +31,15 @@
loadIdentity();
}
+ public Matrix4f(float[] dataArray) {
+ mMat = new float[16];
+ System.arraycopy(dataArray, 0, mMat, 0, mMat.length);
+ }
+
+ public float[] getArray() {
+ return mMat;
+ }
+
public float get(int i, int j) {
return mMat[i*4 + j];
}
@@ -147,6 +156,10 @@
mMat[14]= -(f + n) / (f - n);
}
+ public void loadOrthoWindow(int w, int h) {
+ loadOrtho(0,w, h,0, -1,1);
+ }
+
public void loadFrustum(float l, float r, float b, float t, float n, float f) {
loadIdentity();
mMat[0] = 2 * n / (r - l);
@@ -159,6 +172,14 @@
mMat[15]= 0;
}
+ public void loadPerspective(float fovy, float aspect, float near, float far) {
+ float top = near * (float)Math.tan((float) (fovy * Math.PI / 360.0f));
+ float bottom = -top;
+ float left = bottom * aspect;
+ float right = top * aspect;
+ loadFrustum(left, right, bottom, top, near, far);
+ }
+
public void multiply(Matrix4f rhs) {
Matrix4f tmp = new Matrix4f();
tmp.loadMultiply(this, rhs);
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 5f93f5b..0b7262b 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -305,8 +305,8 @@
return rsnFileA3DGetEntryByIndex(mContext, fileA3D, index);
}
- native int rsnFontCreateFromFile(int con, String fileName, int size, int dpi);
- synchronized int nFontCreateFromFile(String fileName, int size, int dpi) {
+ native int rsnFontCreateFromFile(int con, String fileName, float size, int dpi);
+ synchronized int nFontCreateFromFile(String fileName, float size, int dpi) {
return rsnFontCreateFromFile(mContext, fileName, size, dpi);
}
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index a8343b3..493653a 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -623,7 +623,7 @@
// -----------------------------------
static int
-nFontCreateFromFile(JNIEnv *_env, jobject _this, RsContext con, jstring fileName, jint fontSize, jint dpi)
+nFontCreateFromFile(JNIEnv *_env, jobject _this, RsContext con, jstring fileName, jfloat fontSize, jint dpi)
{
const char* fileNameUTF = _env->GetStringUTFChars(fileName, NULL);
@@ -1239,7 +1239,7 @@
{"rsnFileA3DGetIndexEntries", "(III[I[Ljava/lang/String;)V", (void*)nFileA3DGetIndexEntries },
{"rsnFileA3DGetEntryByIndex", "(III)I", (void*)nFileA3DGetEntryByIndex },
-{"rsnFontCreateFromFile", "(ILjava/lang/String;II)I", (void*)nFontCreateFromFile },
+{"rsnFontCreateFromFile", "(ILjava/lang/String;FI)I", (void*)nFontCreateFromFile },
{"rsnElementCreate", "(IIIZI)I", (void*)nElementCreate },
{"rsnElementCreate2", "(I[I[Ljava/lang/String;[I)I", (void*)nElementCreate2 },
diff --git a/include/media/mediascanner.h b/include/media/mediascanner.h
index 74c9d5d..df5be32 100644
--- a/include/media/mediascanner.h
+++ b/include/media/mediascanner.h
@@ -71,7 +71,8 @@
bool addStringTag(const char* name, const char* value);
void endFile();
- virtual bool scanFile(const char* path, long long lastModified, long long fileSize) = 0;
+ virtual bool scanFile(const char* path, long long lastModified,
+ long long fileSize, bool isDirectory) = 0;
virtual bool handleStringTag(const char* name, const char* value) = 0;
virtual bool setMimeType(const char* mimeType) = 0;
virtual bool addNoMediaFolder(const char* path) = 0;
diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java
index 6cb50b8..7d99686 100644
--- a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java
+++ b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java
@@ -23,6 +23,7 @@
import android.content.res.Resources;
import android.renderscript.*;
import android.renderscript.Element.Builder;
+import android.renderscript.Font.Style;
import android.renderscript.ProgramStore.DepthFunc;
import android.util.Log;
@@ -186,22 +187,20 @@
FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.robot);
FileA3D.IndexEntry entry = model.getIndexEntry(0);
- if (entry == null || entry.getClassID() != FileA3D.ClassID.MESH) {
+ if (entry == null || entry.getEntryType() != FileA3D.EntryType.MESH) {
Log.e("rs", "could not load model");
} else {
mMesh = (Mesh)entry.getObject();
mScript.set_gTestMesh(mMesh);
}
- mItalic = Font.create(mRS, mRes, "DroidSerif-Italic.ttf", 8);
+ mItalic = Font.create(mRS, mRes, "serif", Font.Style.ITALIC, 8);
mScript.set_gItalic(mItalic);
initTextAllocation();
initTransformHierarchy();
- Log.v("========SceneGraph========", "transform hierarchy initialized");
-
mScript.bind_gRootNode(mRootTransform.getField());
mScript.bind_gGroup(mGroup1.mParent.mChildField);
diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java
index 747463a..5451ca1 100644
--- a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java
+++ b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java
@@ -148,14 +148,14 @@
FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.robot);
FileA3D.IndexEntry entry = model.getIndexEntry(0);
- if (entry == null || entry.getClassID() != FileA3D.ClassID.MESH) {
+ if (entry == null || entry.getEntryType() != FileA3D.EntryType.MESH) {
Log.e("rs", "could not load model");
} else {
mMesh = (Mesh)entry.getObject();
mScript.set_gTestMesh(mMesh);
}
- mItalic = Font.create(mRS, mRes, "DroidSerif-Italic.ttf", 8);
+ mItalic = Font.create(mRS, mRes, "serif", Font.Style.ITALIC, 8);
mScript.set_gItalic(mItalic);
initTextAllocation();
diff --git a/libs/rs/java/Samples/src/com/android/samples/RsBenchRS.java b/libs/rs/java/Samples/src/com/android/samples/RsBenchRS.java
index ddb05b3..b3e8026 100644
--- a/libs/rs/java/Samples/src/com/android/samples/RsBenchRS.java
+++ b/libs/rs/java/Samples/src/com/android/samples/RsBenchRS.java
@@ -315,22 +315,15 @@
private void initFonts() {
// Sans font by family name
- mFontSans = Font.createFromFamily(mRS, mRes, "sans-serif",
- Font.Style.NORMAL, 8);
- // Create font by file name
- mFontSerif = Font.create(mRS, mRes, "DroidSerif-Regular.ttf", 8);
+ mFontSans = Font.create(mRS, mRes, "sans-serif", Font.Style.NORMAL, 8);
+ mFontSerif = Font.create(mRS, mRes, "serif", Font.Style.NORMAL, 8);
// Create fonts by family and style
- mFontSerifBold = Font.createFromFamily(mRS, mRes, "serif",
- Font.Style.BOLD, 8);
- mFontSerifItalic = Font.createFromFamily(mRS, mRes, "serif",
- Font.Style.ITALIC, 8);
- mFontSerifBoldItalic = Font.createFromFamily(mRS, mRes, "serif",
- Font.Style.BOLD_ITALIC, 8);
- mFontMono = Font.createFromFamily(mRS, mRes, "mono",
- Font.Style.NORMAL, 8);
+ mFontSerifBold = Font.create(mRS, mRes, "serif", Font.Style.BOLD, 8);
+ mFontSerifItalic = Font.create(mRS, mRes, "serif", Font.Style.ITALIC, 8);
+ mFontSerifBoldItalic = Font.create(mRS, mRes, "serif", Font.Style.BOLD_ITALIC, 8);
+ mFontMono = Font.create(mRS, mRes, "mono", Font.Style.NORMAL, 8);
- mTextAlloc = Allocation.createFromString(mRS, "String from allocation",
- Allocation.USAGE_SCRIPT);
+ mTextAlloc = Allocation.createFromString(mRS, "String from allocation", Allocation.USAGE_SCRIPT);
mScript.set_gFontSans(mFontSans);
mScript.set_gFontSerif(mFontSerif);
@@ -351,7 +344,7 @@
FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.torus);
FileA3D.IndexEntry entry = model.getIndexEntry(0);
- if (entry == null || entry.getClassID() != FileA3D.ClassID.MESH) {
+ if (entry == null || entry.getEntryType() != FileA3D.EntryType.MESH) {
Log.e("rs", "could not load model");
} else {
mTorus = (Mesh)entry.getObject();
diff --git a/libs/rs/java/Samples/src/com/android/samples/RsListRS.java b/libs/rs/java/Samples/src/com/android/samples/RsListRS.java
index 223f552..8e2d51f 100644
--- a/libs/rs/java/Samples/src/com/android/samples/RsListRS.java
+++ b/libs/rs/java/Samples/src/com/android/samples/RsListRS.java
@@ -134,7 +134,7 @@
mScript.bind_gList(mListAllocs);
- mItalic = Font.createFromFamily(mRS, mRes, "serif", Font.Style.BOLD_ITALIC, 8);
+ mItalic = Font.create(mRS, mRes, "serif", Font.Style.BOLD_ITALIC, 8);
mScript.set_gItalic(mItalic);
mRS.bindRootScript(mScript);
diff --git a/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java b/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java
index 75e8d99..636a486 100644
--- a/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java
+++ b/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java
@@ -23,6 +23,7 @@
import android.graphics.BitmapFactory;
import android.renderscript.*;
import android.renderscript.Allocation.CubemapLayout;
+import android.renderscript.Font.Style;
import android.renderscript.Program.TextureType;
import android.renderscript.ProgramStore.DepthFunc;
import android.renderscript.Sampler.Value;
@@ -304,14 +305,13 @@
private void initFonts() {
// Sans font by family name
- mFontSans = Font.createFromFamily(mRS, mRes, "sans-serif", Font.Style.NORMAL, 8);
- // Create font by file name
- mFontSerif = Font.create(mRS, mRes, "DroidSerif-Regular.ttf", 8);
+ mFontSans = Font.create(mRS, mRes, "sans-serif", Font.Style.NORMAL, 8);
+ mFontSerif = Font.create(mRS, mRes, "serif", Font.Style.NORMAL, 8);
// Create fonts by family and style
- mFontSerifBold = Font.createFromFamily(mRS, mRes, "serif", Font.Style.BOLD, 8);
- mFontSerifItalic = Font.createFromFamily(mRS, mRes, "serif", Font.Style.ITALIC, 8);
- mFontSerifBoldItalic = Font.createFromFamily(mRS, mRes, "serif", Font.Style.BOLD_ITALIC, 8);
- mFontMono = Font.createFromFamily(mRS, mRes, "mono", Font.Style.NORMAL, 8);
+ mFontSerifBold = Font.create(mRS, mRes, "serif", Font.Style.BOLD, 8);
+ mFontSerifItalic = Font.create(mRS, mRes, "serif", Font.Style.ITALIC, 8);
+ mFontSerifBoldItalic = Font.create(mRS, mRes, "serif", Font.Style.BOLD_ITALIC, 8);
+ mFontMono = Font.create(mRS, mRes, "mono", Font.Style.NORMAL, 8);
mTextAlloc = Allocation.createFromString(mRS, "String from allocation", Allocation.USAGE_SCRIPT);
@@ -330,7 +330,7 @@
FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.torus);
FileA3D.IndexEntry entry = model.getIndexEntry(0);
- if (entry == null || entry.getClassID() != FileA3D.ClassID.MESH) {
+ if (entry == null || entry.getEntryType() != FileA3D.EntryType.MESH) {
Log.e("rs", "could not load model");
} else {
mTorus = (Mesh)entry.getObject();
diff --git a/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java b/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java
index 265e1d6..a50321e 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java
+++ b/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java
@@ -94,7 +94,7 @@
mScript.bind_gList(mListAllocs);
- mFont = Font.createFromFamily(mRS, mRes, "serif", Font.Style.BOLD, 8);
+ mFont = Font.create(mRS, mRes, "serif", Font.Style.BOLD, 8);
mScript.set_gFont(mFont);
mRS.bindRootScript(mScript);
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index 5daba08..cf94060 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -420,7 +420,7 @@
FontCreateFromFile {
param const char *name
- param uint32_t fontSize
+ param float fontSize
param uint32_t dpi
ret RsFont
}
diff --git a/libs/rs/rsFont.cpp b/libs/rs/rsFont.cpp
index 2fa1f0a..80bca43 100644
--- a/libs/rs/rsFont.cpp
+++ b/libs/rs/rsFont.cpp
@@ -40,20 +40,15 @@
mFace = NULL;
}
-bool Font::init(const char *name, uint32_t fontSize, uint32_t dpi) {
+bool Font::init(const char *name, float fontSize, uint32_t dpi) {
if (mInitialized) {
LOGE("Reinitialization of fonts not supported");
return false;
}
- String8 fontsDir("/fonts/");
- String8 fullPath(getenv("ANDROID_ROOT"));
- fullPath += fontsDir;
- fullPath += name;
-
- FT_Error error = FT_New_Face(mRSC->mStateFont.getLib(), fullPath.string(), 0, &mFace);
+ FT_Error error = FT_New_Face(mRSC->mStateFont.getLib(), name, 0, &mFace);
if (error) {
- LOGE("Unable to initialize font %s", fullPath.string());
+ LOGE("Unable to initialize font %s", name);
return false;
}
@@ -61,9 +56,9 @@
mFontSize = fontSize;
mDpi = dpi;
- error = FT_Set_Char_Size(mFace, fontSize * 64, 0, dpi, 0);
+ error = FT_Set_Char_Size(mFace, (FT_F26Dot6)(fontSize * 64.0f), 0, dpi, 0);
if (error) {
- LOGE("Unable to set font size on %s", fullPath.string());
+ LOGE("Unable to set font size on %s", name);
return false;
}
@@ -278,7 +273,7 @@
return newGlyph;
}
-Font * Font::create(Context *rsc, const char *name, uint32_t fontSize, uint32_t dpi) {
+Font * Font::create(Context *rsc, const char *name, float fontSize, uint32_t dpi) {
rsc->mStateFont.checkInit();
Vector<Font*> &activeFonts = rsc->mStateFont.mActiveFonts;
@@ -332,31 +327,20 @@
// Get the gamma
float gamma = DEFAULT_TEXT_GAMMA;
if (property_get(PROPERTY_TEXT_GAMMA, property, NULL) > 0) {
- LOGD(" Setting text gamma to %s", property);
gamma = atof(property);
- } else {
- LOGD(" Using default text gamma of %.2f", DEFAULT_TEXT_GAMMA);
}
// Get the black gamma threshold
int32_t blackThreshold = DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD;
if (property_get(PROPERTY_TEXT_BLACK_GAMMA_THRESHOLD, property, NULL) > 0) {
- LOGD(" Setting text black gamma threshold to %s", property);
blackThreshold = atoi(property);
- } else {
- LOGD(" Using default text black gamma threshold of %d",
- DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD);
}
mBlackThreshold = (float)(blackThreshold) / 255.0f;
// Get the white gamma threshold
int32_t whiteThreshold = DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD;
if (property_get(PROPERTY_TEXT_WHITE_GAMMA_THRESHOLD, property, NULL) > 0) {
- LOGD(" Setting text white gamma threshold to %s", property);
whiteThreshold = atoi(property);
- } else {
- LOGD(" Using default white black gamma threshold of %d",
- DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD);
}
mWhiteThreshold = (float)(whiteThreshold) / 255.0f;
@@ -735,7 +719,11 @@
Font *currentFont = mRSC->getFont();
if (!currentFont) {
if (!mDefault.get()) {
- mDefault.set(Font::create(mRSC, "DroidSans.ttf", 16, 96));
+ String8 fontsDir("/fonts/DroidSans.ttf");
+ String8 fullPath(getenv("ANDROID_ROOT"));
+ fullPath += fontsDir;
+
+ mDefault.set(Font::create(mRSC, fullPath.string(), 16, 96));
}
currentFont = mDefault.get();
}
@@ -815,7 +803,7 @@
namespace android {
namespace renderscript {
-RsFont rsi_FontCreateFromFile(Context *rsc, char const *name, uint32_t fontSize, uint32_t dpi) {
+RsFont rsi_FontCreateFromFile(Context *rsc, char const *name, float fontSize, uint32_t dpi) {
Font *newFont = Font::create(rsc, name, fontSize, dpi);
if (newFont) {
newFont->incUserRef();
diff --git a/libs/rs/rsFont.h b/libs/rs/rsFont.h
index 0f6815d..c24c9f1 100644
--- a/libs/rs/rsFont.h
+++ b/libs/rs/rsFont.h
@@ -73,7 +73,7 @@
return RS_A3D_CLASS_ID_UNKNOWN;
}
- static Font * create(Context *rsc, const char *name, uint32_t fontSize, uint32_t dpi);
+ static Font * create(Context *rsc, const char *name, float fontSize, uint32_t dpi);
protected:
@@ -112,11 +112,11 @@
};
String8 mFontName;
- uint32_t mFontSize;
+ float mFontSize;
uint32_t mDpi;
Font(Context *rsc);
- bool init(const char *name, uint32_t fontSize, uint32_t dpi);
+ bool init(const char *name, float fontSize, uint32_t dpi);
FT_Face mFace;
bool mInitialized;
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 63ec6b2..ae6dd61 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -388,7 +388,14 @@
String prop = SystemProperties.get("drm.service.enabled");
return prop != null && prop.equals("true");
}
-
+
+ private final String mediaToExternalPath(String path) {
+ if (mMediaStoragePath != null && path.startsWith(mMediaStoragePath)) {
+ path = mExternalStoragePath + path.substring(mMediaStoragePath.length());
+ }
+ return path;
+ }
+
private class MyMediaScannerClient implements MediaScannerClient {
private String mArtist;
@@ -407,70 +414,74 @@
private long mFileSize;
private String mWriter;
- public FileCacheEntry beginFile(String path, String mimeType, long lastModified, long fileSize) {
-
- // special case certain file names
- // I use regionMatches() instead of substring() below
- // to avoid memory allocation
- int lastSlash = path.lastIndexOf('/');
- if (lastSlash >= 0 && lastSlash + 2 < path.length()) {
- // ignore those ._* files created by MacOS
- if (path.regionMatches(lastSlash + 1, "._", 0, 2)) {
- return null;
- }
-
- // ignore album art files created by Windows Media Player:
- // Folder.jpg, AlbumArtSmall.jpg, AlbumArt_{...}_Large.jpg and AlbumArt_{...}_Small.jpg
- if (path.regionMatches(true, path.length() - 4, ".jpg", 0, 4)) {
- if (path.regionMatches(true, lastSlash + 1, "AlbumArt_{", 0, 10) ||
- path.regionMatches(true, lastSlash + 1, "AlbumArt.", 0, 9)) {
- return null;
- }
- int length = path.length() - lastSlash - 1;
- if ((length == 17 && path.regionMatches(true, lastSlash + 1, "AlbumArtSmall", 0, 13)) ||
- (length == 10 && path.regionMatches(true, lastSlash + 1, "Folder", 0, 6))) {
- return null;
- }
- }
- }
-
+ public FileCacheEntry beginFile(String path, String mimeType, long lastModified,
+ long fileSize, boolean isDirectory) {
mMimeType = mimeType;
mFileType = 0;
mFileSize = fileSize;
- // try mimeType first, if it is specified
- if (mimeType != null) {
- mFileType = MediaFile.getFileTypeForMimeType(mimeType);
- }
-
- // if mimeType was not specified, compute file type based on file extension.
- if (mFileType == 0) {
- MediaFile.MediaFileType mediaFileType = MediaFile.getFileType(path);
- if (mediaFileType != null) {
- mFileType = mediaFileType.fileType;
- if (mMimeType == null) {
- mMimeType = mediaFileType.mimeType;
+ if (!isDirectory) {
+ // special case certain file names
+ // I use regionMatches() instead of substring() below
+ // to avoid memory allocation
+ int lastSlash = path.lastIndexOf('/');
+ if (lastSlash >= 0 && lastSlash + 2 < path.length()) {
+ // ignore those ._* files created by MacOS
+ if (path.regionMatches(lastSlash + 1, "._", 0, 2)) {
+ return null;
}
+
+ // ignore album art files created by Windows Media Player:
+ // Folder.jpg, AlbumArtSmall.jpg, AlbumArt_{...}_Large.jpg
+ // and AlbumArt_{...}_Small.jpg
+ if (path.regionMatches(true, path.length() - 4, ".jpg", 0, 4)) {
+ if (path.regionMatches(true, lastSlash + 1, "AlbumArt_{", 0, 10) ||
+ path.regionMatches(true, lastSlash + 1, "AlbumArt.", 0, 9)) {
+ return null;
+ }
+ int length = path.length() - lastSlash - 1;
+ if ((length == 17 && path.regionMatches(
+ true, lastSlash + 1, "AlbumArtSmall", 0, 13)) ||
+ (length == 10
+ && path.regionMatches(true, lastSlash + 1, "Folder", 0, 6))) {
+ return null;
+ }
+ }
+ }
+
+ // try mimeType first, if it is specified
+ if (mimeType != null) {
+ mFileType = MediaFile.getFileTypeForMimeType(mimeType);
+ }
+
+ // if mimeType was not specified, compute file type based on file extension.
+ if (mFileType == 0) {
+ MediaFile.MediaFileType mediaFileType = MediaFile.getFileType(path);
+ if (mediaFileType != null) {
+ mFileType = mediaFileType.fileType;
+ if (mMimeType == null) {
+ mMimeType = mediaFileType.mimeType;
+ }
+ }
+ }
+
+ if (isDrmEnabled() && MediaFile.isDrmFileType(mFileType)) {
+ mFileType = getFileTypeFromDrm(path);
}
}
- if (isDrmEnabled() && MediaFile.isDrmFileType(mFileType)) {
- mFileType = getFileTypeFromDrm(path);
- }
-
- String key = path;
- if (mMediaStoragePath != null && key.startsWith(mMediaStoragePath)) {
- // MediaProvider uses external variant of path for _data, so we need to match
- // against that path instead.
- key = mExternalStoragePath + key.substring(mMediaStoragePath.length());
- }
+ // MediaProvider uses external variant of path for _data, so we need to match
+ // against that path instead.
+ String key = mediaToExternalPath(path);
if (mCaseInsensitivePaths) {
key = path.toLowerCase();
}
FileCacheEntry entry = mFileCache.get(key);
if (entry == null) {
Uri tableUri;
- if (MediaFile.isVideoFileType(mFileType)) {
+ if (isDirectory) {
+ tableUri = mFilesUri;
+ } else if (MediaFile.isVideoFileType(mFileType)) {
tableUri = mVideoUri;
} else if (MediaFile.isImageFileType(mFileType)) {
tableUri = mImagesUri;
@@ -479,7 +490,8 @@
} else {
tableUri = mFilesUri;
}
- entry = new FileCacheEntry(tableUri, 0, path, 0, 0);
+ entry = new FileCacheEntry(tableUri, 0, path, 0,
+ (isDirectory ? MtpConstants.FORMAT_ASSOCIATION : 0));
mFileCache.put(key, entry);
}
entry.mSeenInFileSystem = true;
@@ -514,22 +526,19 @@
return entry;
}
- public void scanFile(String path, long lastModified, long fileSize) {
+ public void scanFile(String path, long lastModified, long fileSize, boolean isDirectory) {
// This is the callback funtion from native codes.
// Log.v(TAG, "scanFile: "+path);
- doScanFile(path, null, lastModified, fileSize, false);
- }
-
- public void scanFile(String path, String mimeType, long lastModified, long fileSize) {
- doScanFile(path, mimeType, lastModified, fileSize, false);
+ doScanFile(path, null, lastModified, fileSize, isDirectory, false);
}
public Uri doScanFile(String path, String mimeType, long lastModified,
- long fileSize, boolean scanAlways) {
+ long fileSize, boolean isDirectory, boolean scanAlways) {
Uri result = null;
// long t1 = System.currentTimeMillis();
try {
- FileCacheEntry entry = beginFile(path, mimeType, lastModified, fileSize);
+ FileCacheEntry entry = beginFile(path, mimeType, lastModified,
+ fileSize, isDirectory);
// rescan for metadata if file was modified since last scan
if (entry != null && (entry.mLastModifiedChanged || scanAlways)) {
String lowpath = path.toLowerCase();
@@ -775,7 +784,11 @@
values.put(MediaStore.MediaColumns.MEDIA_SCANNER_NEW_OBJECT_ID, mMtpObjectHandle);
}
if (tableUri == mFilesUri) {
- values.put(Files.FileColumns.FORMAT, MediaFile.getFormatCode(entry.mPath, mMimeType));
+ int format = entry.mFormat;
+ if (format == 0) {
+ format = MediaFile.getFormatCode(entry.mPath, mMimeType);
+ }
+ values.put(Files.FileColumns.FORMAT, format);
}
// new file, insert it
result = mMediaProvider.insert(tableUri, values);
@@ -872,6 +885,8 @@
}
public void addNoMediaFolder(String path) {
+ path = mediaToExternalPath(path);
+
ContentValues values = new ContentValues();
values.put(MediaStore.Images.ImageColumns.DATA, "");
String [] pathSpec = new String[] {path + '%'};
@@ -930,11 +945,9 @@
}
if (filePath != null) {
- if (mMediaStoragePath != null && filePath.startsWith(mMediaStoragePath)) {
- // MediaProvider uses external variant of path for _data, so we need to query
- // using that path instead.
- filePath = mExternalStoragePath + filePath.substring(mMediaStoragePath.length());
- }
+ // MediaProvider uses external variant of path for _data, so we need to query
+ // using that path instead.
+ filePath = mediaToExternalPath(filePath);
// query for only one file
where = Files.FileColumns.DATA + "=?";
@@ -1060,8 +1073,7 @@
boolean fileMissing = false;
if (!entry.mSeenInFileSystem && !MtpConstants.isAbstractObject(entry.mFormat)) {
- if (entry.mFormat != MtpConstants.FORMAT_ASSOCIATION &&
- inScanDirectory(path, directories)) {
+ if (inScanDirectory(path, directories)) {
// we didn't see this file in the scan directory.
fileMissing = true;
} else {
@@ -1180,7 +1192,7 @@
long lastModifiedSeconds = file.lastModified() / 1000;
// always scan the file, so we can return the content://media Uri for existing files
- return mClient.doScanFile(path, mimeType, lastModifiedSeconds, file.length(), true);
+ return mClient.doScanFile(path, mimeType, lastModifiedSeconds, file.length(),false, true);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException in MediaScanner.scanFile()", e);
return null;
@@ -1204,12 +1216,9 @@
// build file cache so we can look up tracks in the playlist
prescan(null, true);
- String key = path;
- if (mMediaStoragePath != null && key.startsWith(mMediaStoragePath)) {
- // MediaProvider uses external variant of path for _data, so we need to match
- // against that path instead.
- key = mExternalStoragePath + key.substring(mMediaStoragePath.length());
- }
+ // MediaProvider uses external variant of path for _data, so we need to match
+ // against that path instead.
+ String key = mediaToExternalPath(path);
if (mCaseInsensitivePaths) {
key = path.toLowerCase();
}
@@ -1227,7 +1236,8 @@
long lastModifiedSeconds = file.lastModified() / 1000;
// always scan the file, so we can return the content://media Uri for existing files
- mClient.doScanFile(path, mediaFileType.mimeType, lastModifiedSeconds, file.length(), true);
+ mClient.doScanFile(path, mediaFileType.mimeType, lastModifiedSeconds, file.length(),
+ (format == MtpConstants.FORMAT_ASSOCIATION), true);
}
} catch (RemoteException e) {
Log.e(TAG, "RemoteException in MediaScanner.scanFile()", e);
diff --git a/media/java/android/media/MediaScannerClient.java b/media/java/android/media/MediaScannerClient.java
index 258c3b4..ac326ef 100644
--- a/media/java/android/media/MediaScannerClient.java
+++ b/media/java/android/media/MediaScannerClient.java
@@ -21,9 +21,7 @@
*/
public interface MediaScannerClient
{
- public void scanFile(String path, long lastModified, long fileSize);
-
- public void scanFile(String path, String mimeType, long lastModified, long fileSize);
+ public void scanFile(String path, long lastModified, long fileSize, boolean isDirectory);
public void addNoMediaFolder(String path);
diff --git a/media/jni/android_media_MediaScanner.cpp b/media/jni/android_media_MediaScanner.cpp
index fd0b233..a5176fa 100644
--- a/media/jni/android_media_MediaScanner.cpp
+++ b/media/jni/android_media_MediaScanner.cpp
@@ -62,7 +62,7 @@
}
else {
mScanFileMethodID = env->GetMethodID(mediaScannerClientInterface, "scanFile",
- "(Ljava/lang/String;JJ)V");
+ "(Ljava/lang/String;JJZ)V");
mHandleStringTagMethodID = env->GetMethodID(mediaScannerClientInterface, "handleStringTag",
"(Ljava/lang/String;Ljava/lang/String;)V");
mSetMimeTypeMethodID = env->GetMethodID(mediaScannerClientInterface, "setMimeType",
@@ -78,12 +78,14 @@
}
// returns true if it succeeded, false if an exception occured in the Java code
- virtual bool scanFile(const char* path, long long lastModified, long long fileSize)
+ virtual bool scanFile(const char* path, long long lastModified,
+ long long fileSize, bool isDirectory)
{
jstring pathStr;
if ((pathStr = mEnv->NewStringUTF(path)) == NULL) return false;
- mEnv->CallVoidMethod(mClient, mScanFileMethodID, pathStr, lastModified, fileSize);
+ mEnv->CallVoidMethod(mClient, mScanFileMethodID, pathStr, lastModified,
+ fileSize, isDirectory);
mEnv->DeleteLocalRef(pathStr);
return (!mEnv->ExceptionCheck());
diff --git a/media/libmedia/MediaScanner.cpp b/media/libmedia/MediaScanner.cpp
index c31b622..5ec573e 100644
--- a/media/libmedia/MediaScanner.cpp
+++ b/media/libmedia/MediaScanner.cpp
@@ -84,6 +84,7 @@
// place to copy file or directory name
char* fileSpot = path + strlen(path);
struct dirent* entry;
+ struct stat statbuf;
// ignore directories that contain a ".nomedia" file
if (pathRemaining >= 8 /* strlen(".nomedia") */ ) {
@@ -125,7 +126,6 @@
// If the type is unknown, stat() the file instead.
// This is sometimes necessary when accessing NFS mounted filesystems, but
// could be needed in other cases well.
- struct stat statbuf;
if (stat(path, &statbuf) == 0) {
if (S_ISREG(statbuf.st_mode)) {
type = DT_REG;
@@ -142,8 +142,15 @@
// for example, the Mac ".Trashes" directory
if (name[0] == '.') continue;
+ // report the directory to the client
+ if (stat(path, &statbuf) == 0) {
+ client.scanFile(path, statbuf.st_mtime, 0, true);
+ }
+
+ // and now process its contents
strcat(fileSpot, "/");
- int err = doProcessDirectory(path, pathRemaining - nameLength - 1, client, exceptionCheck, exceptionEnv);
+ int err = doProcessDirectory(path, pathRemaining - nameLength - 1, client,
+ exceptionCheck, exceptionEnv);
if (err) {
// pass exceptions up - ignore other errors
if (exceptionCheck && exceptionCheck(exceptionEnv)) goto failure;
@@ -151,11 +158,8 @@
continue;
}
} else {
- struct stat statbuf;
stat(path, &statbuf);
- if (statbuf.st_size > 0) {
- client.scanFile(path, statbuf.st_mtime, statbuf.st_size);
- }
+ client.scanFile(path, statbuf.st_mtime, statbuf.st_size, false);
if (exceptionCheck && exceptionCheck(exceptionEnv)) goto failure;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
index c9fd9a9..759c17c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
@@ -39,7 +39,8 @@
public class NotificationPanel extends LinearLayout implements StatusBarPanel,
View.OnClickListener {
- static final String TAG = "NotificationPanel";
+ static final String TAG = "Tablet/NotificationPanel";
+ static final boolean DEBUG = false;
boolean mShowing;
View mTitleArea;
@@ -248,6 +249,7 @@
}
void startAnimation(boolean visible) {
+ if (DEBUG) Slog.d(TAG, "startAnimation(visible=" + visible + ")");
if (mBgAnim != null && mVisible != visible) {
mBgAnim.reverse();
mPositionAnim.reverse();
@@ -303,18 +305,22 @@
if (mPanelBottom == 0) {
// fully closed, no animation necessary
setPanelBottom(0);
- } else {
- // a little bit visible, schedule an animation
+ } else if (mVisible) {
+ if (DEBUG) {
+ Slog.d(TAG, "panelHeight not zero but trying to open; scheduling an anim to open fully");
+ }
startAnimation(true);
}
}
public void onAnimationCancel(Animator animation) {
- //Slog.d(TAG, "onAnimationCancel mBgAlpha=" + mBgAlpha);
+ if (DEBUG) Slog.d(TAG, "onAnimationCancel mBgAlpha=" + mBgAlpha);
+ // force this to zero so we close the window
+ mBgAlpha = 0;
}
public void onAnimationEnd(Animator animation) {
- //Slog.d(TAG, "onAnimationEnd mBgAlpha=" + mBgAlpha);
+ if (DEBUG) Slog.d(TAG, "onAnimationEnd mBgAlpha=" + mBgAlpha);
if (mBgAlpha == 0) {
setVisibility(View.GONE);
}
diff --git a/services/audioflinger/A2dpAudioInterface.cpp b/services/audioflinger/A2dpAudioInterface.cpp
index aee01ab..d926cb1 100644
--- a/services/audioflinger/A2dpAudioInterface.cpp
+++ b/services/audioflinger/A2dpAudioInterface.cpp
@@ -260,6 +260,7 @@
if (pRate) *pRate = lRate;
mDevice = device;
+ mBufferDurationUs = ((bufferSize() * 1000 )/ frameSize() / sampleRate()) * 1000;
return NO_ERROR;
}
@@ -288,6 +289,7 @@
if (mStandby) {
acquire_wake_lock (PARTIAL_WAKE_LOCK, sA2dpWakeLock);
mStandby = false;
+ mLastWriteTime = systemTime();
}
status = init();
@@ -308,6 +310,15 @@
buffer = (char *)buffer + status;
}
+ // if A2DP sink runs abnormally fast, sleep a little so that audioflinger mixer thread
+ // does no spin and starve other threads.
+ // NOTE: It is likely that the A2DP headset is being disconnected
+ nsecs_t now = systemTime();
+ if ((uint32_t)ns2us(now - mLastWriteTime) < (mBufferDurationUs >> 2)) {
+ LOGV("A2DP sink runs too fast");
+ usleep(mBufferDurationUs - (uint32_t)ns2us(now - mLastWriteTime));
+ }
+ mLastWriteTime = now;
return bytes;
}
@@ -316,7 +327,7 @@
standby();
// Simulate audio output timing in case of error
- usleep(((bytes * 1000 )/ frameSize() / sampleRate()) * 1000);
+ usleep(mBufferDurationUs);
return status;
}
diff --git a/services/audioflinger/A2dpAudioInterface.h b/services/audioflinger/A2dpAudioInterface.h
index cef1926..dbe2c6a 100644
--- a/services/audioflinger/A2dpAudioInterface.h
+++ b/services/audioflinger/A2dpAudioInterface.h
@@ -117,6 +117,8 @@
uint32_t mDevice;
bool mClosing;
bool mSuspended;
+ nsecs_t mLastWriteTime;
+ uint32_t mBufferDurationUs;
};
friend class A2dpAudioStreamOut;