diff options
Diffstat (limited to 'core/java')
27 files changed, 342 insertions, 231 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 76a133b..fc00a4c 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -122,7 +122,8 @@ public final class ActivityThread { private static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV; private static final boolean DEBUG_BROADCAST = false; private static final boolean DEBUG_RESULTS = false; - private static final boolean DEBUG_BACKUP = true; + private static final boolean DEBUG_BACKUP = false; + private static final boolean DEBUG_CONFIGURATION = false; private static final long MIN_TIME_BETWEEN_GCS = 5*1000; private static final Pattern PATTERN_SEMICOLON = Pattern.compile(";"); private static final int SQLITE_MEM_RELEASED_EVENT_LOG_TAG = 75003; @@ -2388,6 +2389,8 @@ public final class ActivityThread { appContext.setOuterContext(activity); CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager()); Configuration config = new Configuration(mConfiguration); + if (DEBUG_CONFIGURATION) Log.v(TAG, "Launching activity " + + r.activityInfo.name + " with config " + config); activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent, r.embeddedID, r.lastNonConfigurationInstance, @@ -2954,6 +2957,8 @@ public final class ActivityThread { if (!r.activity.mFinished && !a.mStartedActivity && r.activity.mDecor != null && !r.hideForNow) { if (r.newConfig != null) { + if (DEBUG_CONFIGURATION) Log.v(TAG, "Resuming activity " + + r.activityInfo.name + " with newConfig " + r.newConfig); performConfigurationChanged(r.activity, r.newConfig); r.newConfig = null; } @@ -3195,6 +3200,8 @@ public final class ActivityThread { } } if (r.newConfig != null) { + if (DEBUG_CONFIGURATION) Log.v(TAG, "Updating activity vis " + + r.activityInfo.name + " with new config " + r.newConfig); performConfigurationChanged(r.activity, r.newConfig); r.newConfig = null; } @@ -3476,6 +3483,10 @@ public final class ActivityThread { Configuration changedConfig = null; + if (DEBUG_CONFIGURATION) Log.v(TAG, "Relaunching activity " + + tmp.token + " with configChanges=0x" + + Integer.toHexString(configChanges)); + // First: make sure we have the most recent configuration and most // recent version of the activity, or skip it if some previous call // had taken a more recent version. @@ -3494,6 +3505,7 @@ public final class ActivityThread { } if (tmp == null) { + if (DEBUG_CONFIGURATION) Log.v(TAG, "Abort, activity not relaunching!"); return; } @@ -3503,13 +3515,16 @@ public final class ActivityThread { } } + if (DEBUG_CONFIGURATION) Log.v(TAG, "Relaunching activity " + + tmp.token + ": changedConfig=" + changedConfig); + // If there was a pending configuration change, execute it first. if (changedConfig != null) { handleConfigurationChanged(changedConfig); } ActivityRecord r = mActivities.get(tmp.token); - if (localLOGV) Log.v(TAG, "Handling relaunch of " + r); + if (DEBUG_CONFIGURATION) Log.v(TAG, "Handling relaunch of " + r); if (r == null) { return; } @@ -3595,6 +3610,8 @@ public final class ActivityThread { // the activity manager may, before then, decide the // activity needs to be destroyed to handle its new // configuration. + if (DEBUG_CONFIGURATION) Log.v(TAG, "Setting activity " + + ar.activityInfo.name + " newConfig=" + newConfig); ar.newConfig = newConfig; } } @@ -3652,6 +3669,8 @@ public final class ActivityThread { } } + if (DEBUG_CONFIGURATION) Log.v(TAG, "Config callback " + cb + + ": shouldChangeConfig=" + shouldChangeConfig); if (shouldChangeConfig) { cb.onConfigurationChanged(config); @@ -3679,6 +3698,9 @@ public final class ActivityThread { ArrayList<ComponentCallbacks> callbacks = new ArrayList<ComponentCallbacks>(); + if (DEBUG_CONFIGURATION) Log.v(TAG, "Handle configuration changed: " + + config); + synchronized(mPackages) { if (mConfiguration == null) { mConfiguration = new Configuration(); @@ -3729,6 +3751,9 @@ public final class ActivityThread { return; } + if (DEBUG_CONFIGURATION) Log.v(TAG, "Handle activity config changed: " + + r.activityInfo.name); + performConfigurationChanged(r.activity, mConfiguration); } diff --git a/core/java/android/app/ApplicationContext.java b/core/java/android/app/ApplicationContext.java index 0582e34..8ba7c01 100644 --- a/core/java/android/app/ApplicationContext.java +++ b/core/java/android/app/ApplicationContext.java @@ -2760,6 +2760,7 @@ class ApplicationContext extends Context { if (mFile.exists()) { if (!mFile.renameTo(mBackupFile)) { Log.e(TAG, "Couldn't rename file " + mFile + " to backup file " + mBackupFile); + return false; } } diff --git a/core/java/android/app/BackupAgent.java b/core/java/android/app/BackupAgent.java index 0ac8a1e..b207998 100644 --- a/core/java/android/app/BackupAgent.java +++ b/core/java/android/app/BackupAgent.java @@ -36,6 +36,7 @@ import java.io.IOException; */ public abstract class BackupAgent extends ContextWrapper { private static final String TAG = "BackupAgent"; + private static final boolean DEBUG = false; public BackupAgent() { super(null); @@ -116,7 +117,7 @@ public abstract class BackupAgent extends ContextWrapper { ParcelFileDescriptor data, ParcelFileDescriptor newState) throws RemoteException { // !!! TODO - real implementation; for now just invoke the callbacks directly - Log.v(TAG, "doBackup() invoked"); + if (DEBUG) Log.v(TAG, "doBackup() invoked"); BackupDataOutput output = new BackupDataOutput(data.getFileDescriptor()); try { BackupAgent.this.onBackup(oldState, output, newState); @@ -132,7 +133,7 @@ public abstract class BackupAgent extends ContextWrapper { public void doRestore(ParcelFileDescriptor data, int appVersionCode, ParcelFileDescriptor newState) throws RemoteException { // !!! TODO - real implementation; for now just invoke the callbacks directly - Log.v(TAG, "doRestore() invoked"); + if (DEBUG) Log.v(TAG, "doRestore() invoked"); BackupDataInput input = new BackupDataInput(data.getFileDescriptor()); try { BackupAgent.this.onRestore(input, appVersionCode, newState); diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index 38cac87..69c87ee 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -44,6 +44,12 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +/** + * Provides access to the system wallpaper. With WallpaperManager, you can + * get the current wallpaper, get the desired dimensions for the wallpaper, set + * the wallpaper, and more. Get an instance of WallpaperManager with + * {@link #getInstance(android.content.Context) getInstance()}. + */ public class WallpaperManager { private static String TAG = "WallpaperManager"; private static boolean DEBUG = false; @@ -310,8 +316,11 @@ public class WallpaperManager { } /** - * Like {@link #peekDrawable}, but always returns a valid Drawable. If + * Retrieve the current system wallpaper; if * no wallpaper is set, the system default wallpaper is returned. + * This is returned as an + * abstract Drawable that you can install in a View to display whatever + * wallpaper the user has currently set. * * @return Returns a Drawable object that will draw the wallpaper. */ @@ -326,10 +335,10 @@ public class WallpaperManager { } /** - * Retrieve the current system wallpaper. This is returned as an + * Retrieve the current system wallpaper; if there is no wallpaper set, + * a null pointer is returned. This is returned as an * abstract Drawable that you can install in a View to display whatever - * wallpaper the user has currently set. If there is no wallpaper set, - * a null pointer is returned. + * wallpaper the user has currently set. * * @return Returns a Drawable object that will draw the wallpaper or a * null pointer if these is none. @@ -345,8 +354,15 @@ public class WallpaperManager { } /** - * Like {@link #peekFastDrawable}, but always returns a valid Drawable. If - * no wallpaper is set, the system default wallpaper is returned. + * Like {@link #getDrawable()}, but the returned Drawable has a number + * of limitations to reduce its overhead as much as possible. It will + * never scale the wallpaper (only centering it if the requested bounds + * do match the bitmap bounds, which should not be typical), doesn't + * allow setting an alpha, color filter, or other attributes, etc. The + * bounds of the returned drawable will be initialized to the same bounds + * as the wallpaper, so normally you will not need to touch it. The + * drawable also assumes that it will be used in a context running in + * the same density as the screen (not in density compatibility mode). * * @return Returns a Drawable object that will draw the wallpaper. */ @@ -360,15 +376,8 @@ public class WallpaperManager { } /** - * Like {@link #peekDrawable()}, but the returned Drawable has a number - * of limitations to reduce its overhead as much as possible: it will - * never scale the wallpaper (only centering it if the requested bounds - * do match the bitmap bounds, which should not be typical), doesn't - * allow setting an alpha, color filter, or other attributes, etc. The - * bounds of the returned drawable will be initialized to the same bounds - * as the wallpaper, so normally you will not need to touch it. The - * drawable also assumes that it will be used in a context running in - * the same density as the screen (not in density compatibility mode). + * Like {@link #getFastDrawable()}, but if there is no wallpaper set, + * a null pointer is returned. * * @return Returns an optimized Drawable object that will draw the * wallpaper or a null pointer if these is none. @@ -566,7 +575,7 @@ public class WallpaperManager { * make sense when the wallpaper is larger than the screen. * * @param windowToken The window who these offsets should be associated - * with, as returned by {@link android.view.View#getWindowVisibility() + * with, as returned by {@link android.view.View#getWindowToken() * View.getWindowToken()}. * @param xOffset The offset olong the X dimension, from 0 to 1. * @param yOffset The offset along the Y dimension, from 0 to 1. @@ -589,7 +598,7 @@ public class WallpaperManager { * to scroll from whatever its last offsets were. * * @param windowToken The window who these offsets should be associated - * with, as returned by {@link android.view.View#getWindowVisibility() + * with, as returned by {@link android.view.View#getWindowToken() * View.getWindowToken()}. */ public void clearWallpaperOffsets(IBinder windowToken) { diff --git a/core/java/android/backup/AbsoluteFileBackupHelper.java b/core/java/android/backup/AbsoluteFileBackupHelper.java index ab24675..1dbccc9 100644 --- a/core/java/android/backup/AbsoluteFileBackupHelper.java +++ b/core/java/android/backup/AbsoluteFileBackupHelper.java @@ -31,6 +31,7 @@ import java.io.FileDescriptor; */ public class AbsoluteFileBackupHelper extends FileBackupHelperBase implements BackupHelper { private static final String TAG = "AbsoluteFileBackupHelper"; + private static final boolean DEBUG = false; Context mContext; String[] mFiles; @@ -54,8 +55,7 @@ public class AbsoluteFileBackupHelper extends FileBackupHelperBase implements Ba } public void restoreEntity(BackupDataInputStream data) { - // TODO: turn this off before ship - Log.d(TAG, "got entity '" + data.getKey() + "' size=" + data.size()); + if (DEBUG) Log.d(TAG, "got entity '" + data.getKey() + "' size=" + data.size()); String key = data.getKey(); if (isKeyInList(key, mFiles)) { File f = new File(key); diff --git a/core/java/android/backup/FileBackupHelper.java b/core/java/android/backup/FileBackupHelper.java index 4058497..dacfc8f 100644 --- a/core/java/android/backup/FileBackupHelper.java +++ b/core/java/android/backup/FileBackupHelper.java @@ -26,6 +26,7 @@ import java.io.FileDescriptor; /** @hide */ public class FileBackupHelper extends FileBackupHelperBase implements BackupHelper { private static final String TAG = "FileBackupHelper"; + private static final boolean DEBUG = false; Context mContext; File mFilesDir; @@ -60,8 +61,7 @@ public class FileBackupHelper extends FileBackupHelperBase implements BackupHelp } public void restoreEntity(BackupDataInputStream data) { - // TODO: turn this off before ship - Log.d(TAG, "got entity '" + data.getKey() + "' size=" + data.size()); + if (DEBUG) Log.d(TAG, "got entity '" + data.getKey() + "' size=" + data.size()); String key = data.getKey(); if (isKeyInList(key, mFiles)) { File f = new File(mFilesDir, key); diff --git a/core/java/android/backup/SharedPreferencesBackupHelper.java b/core/java/android/backup/SharedPreferencesBackupHelper.java index 4a7b399..6a0bc96 100644 --- a/core/java/android/backup/SharedPreferencesBackupHelper.java +++ b/core/java/android/backup/SharedPreferencesBackupHelper.java @@ -26,6 +26,7 @@ import java.io.FileDescriptor; /** @hide */ public class SharedPreferencesBackupHelper extends FileBackupHelperBase implements BackupHelper { private static final String TAG = "SharedPreferencesBackupHelper"; + private static final boolean DEBUG = false; private Context mContext; private String[] mPrefGroups; @@ -56,9 +57,9 @@ public class SharedPreferencesBackupHelper extends FileBackupHelperBase implemen public void restoreEntity(BackupDataInputStream data) { Context context = mContext; - // TODO: turn this off before ship - Log.d(TAG, "got entity '" + data.getKey() + "' size=" + data.size()); String key = data.getKey(); + if (DEBUG) Log.d(TAG, "got entity '" + key + "' size=" + data.size()); + if (isKeyInList(key, mPrefGroups)) { File f = context.getSharedPrefsFile(key).getAbsoluteFile(); writeFile(f, data); diff --git a/core/java/android/bluetooth/HeadsetBase.java b/core/java/android/bluetooth/HeadsetBase.java index 29cf41d..e2935c9 100644 --- a/core/java/android/bluetooth/HeadsetBase.java +++ b/core/java/android/bluetooth/HeadsetBase.java @@ -211,9 +211,10 @@ public final class HeadsetBase { */ public boolean connectAsync() { - return connectAsyncNative(); + int ret = connectAsyncNative(); + return (ret == 0) ? true : false; } - private native boolean connectAsyncNative(); + private native int connectAsyncNative(); public int getRemainingAsyncConnectWaitingTimeMs() { return mTimeoutRemainingMs; diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 5fb5768..b785dbf 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -1330,7 +1330,7 @@ public class Intent implements Parcelable { public static final String ACTION_UID_REMOVED = "android.intent.action.UID_REMOVED"; /** * Broadcast Action: The current system wallpaper has changed. See - * {@link Context#getWallpaper} for retrieving the new wallpaper. + * {@link android.app.WallpaperManager} for retrieving the new wallpaper. */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_WALLPAPER_CHANGED = "android.intent.action.WALLPAPER_CHANGED"; diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java index 11d984d..fb2608a 100644 --- a/core/java/android/content/SyncStorageEngine.java +++ b/core/java/android/content/SyncStorageEngine.java @@ -103,7 +103,7 @@ public class SyncStorageEngine extends Handler { public static final String MESG_SUCCESS = "success"; public static final String MESG_CANCELED = "canceled"; - public static final int MAX_HISTORY = 15; + public static final int MAX_HISTORY = 100; private static final int MSG_WRITE_STATUS = 1; private static final long WRITE_STATUS_DELAY = 1000*60*10; // 10 minutes diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 3e117d4..83e63b9 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -986,6 +986,7 @@ public class PackageParser { } final int NP = PackageParser.NEW_PERMISSIONS.length; + StringBuilder implicitPerms = null; for (int ip=0; ip<NP; ip++) { final PackageParser.NewPermissionInfo npi = PackageParser.NEW_PERMISSIONS[ip]; @@ -993,11 +994,20 @@ public class PackageParser { break; } if (!pkg.requestedPermissions.contains(npi.name)) { - Log.i(TAG, "Impliciting adding " + npi.name + " to old pkg " - + pkg.packageName); + if (implicitPerms == null) { + implicitPerms = new StringBuilder(128); + implicitPerms.append(pkg.packageName); + implicitPerms.append(": compat added "); + } else { + implicitPerms.append(' '); + } + implicitPerms.append(npi.name); pkg.requestedPermissions.add(npi.name); } } + if (implicitPerms != null) { + Log.i(TAG, implicitPerms.toString()); + } if (supportsSmallScreens < 0 || (supportsSmallScreens > 0 && pkg.applicationInfo.targetSdkVersion @@ -1335,8 +1345,10 @@ public class PackageParser { com.android.internal.R.styleable.AndroidManifestApplication_backupAgent); if (backupAgent != null) { ai.backupAgentName = buildClassName(pkgName, backupAgent, outError); - Log.v(TAG, "android:backupAgent = " + ai.backupAgentName - + " from " + pkgName + "+" + backupAgent); + if (false) { + Log.v(TAG, "android:backupAgent = " + ai.backupAgentName + + " from " + pkgName + "+" + backupAgent); + } if (sa.getBoolean( com.android.internal.R.styleable.AndroidManifestApplication_killAfterRestore, @@ -1526,8 +1538,9 @@ public class PackageParser { } else { if (!RIGID_PARSER) { - Log.w(TAG, "Problem in package " + mArchiveSourcePath + ":"); - Log.w(TAG, "Unknown element under <application>: " + tagName); + Log.w(TAG, "Unknown element under <application>: " + tagName + + " at " + mArchiveSourcePath + " " + + parser.getPositionDescription()); XmlUtils.skipCurrentTag(parser); continue; } else { @@ -1572,25 +1585,6 @@ public class PackageParser { return true; } - private boolean parseComponentInfo(Package owner, int flags, - ComponentInfo outInfo, String[] outError, String tag, TypedArray sa, - int nameRes, int labelRes, int iconRes, int processRes, - int enabledRes) { - if (!parsePackageItemInfo(owner, outInfo, outError, tag, sa, - nameRes, labelRes, iconRes)) { - return false; - } - - if (processRes != 0) { - outInfo.processName = buildProcessName(owner.applicationInfo.packageName, - owner.applicationInfo.processName, sa.getNonResourceString(processRes), - flags, mSeparateProcesses, outError); - } - outInfo.enabled = sa.getBoolean(enabledRes, true); - - return outError[0] == null; - } - private Activity parseActivity(Package owner, Resources res, XmlPullParser parser, AttributeSet attrs, int flags, String[] outError, boolean receiver) throws XmlPullParserException, IOException { @@ -1749,9 +1743,13 @@ public class PackageParser { if (!RIGID_PARSER) { Log.w(TAG, "Problem in package " + mArchiveSourcePath + ":"); if (receiver) { - Log.w(TAG, "Unknown element under <receiver>: " + parser.getName()); + Log.w(TAG, "Unknown element under <receiver>: " + parser.getName() + + " at " + mArchiveSourcePath + " " + + parser.getPositionDescription()); } else { - Log.w(TAG, "Unknown element under <activity>: " + parser.getName()); + Log.w(TAG, "Unknown element under <activity>: " + parser.getName() + + " at " + mArchiveSourcePath + " " + + parser.getPositionDescription()); } XmlUtils.skipCurrentTag(parser); continue; @@ -1891,8 +1889,9 @@ public class PackageParser { } } else { if (!RIGID_PARSER) { - Log.w(TAG, "Problem in package " + mArchiveSourcePath + ":"); - Log.w(TAG, "Unknown element under <activity-alias>: " + parser.getName()); + Log.w(TAG, "Unknown element under <activity-alias>: " + parser.getName() + + " at " + mArchiveSourcePath + " " + + parser.getPositionDescription()); XmlUtils.skipCurrentTag(parser); continue; } @@ -2055,8 +2054,9 @@ public class PackageParser { outInfo.info.grantUriPermissions = true; } else { if (!RIGID_PARSER) { - Log.w(TAG, "Problem in package " + mArchiveSourcePath + ":"); - Log.w(TAG, "No path, pathPrefix, or pathPattern for <path-permission>"); + Log.w(TAG, "Unknown element under <path-permission>: " + + parser.getName() + " at " + mArchiveSourcePath + " " + + parser.getPositionDescription()); XmlUtils.skipCurrentTag(parser); continue; } @@ -2096,8 +2096,9 @@ public class PackageParser { if (!havePerm) { if (!RIGID_PARSER) { - Log.w(TAG, "Problem in package " + mArchiveSourcePath + ":"); - Log.w(TAG, "No readPermission or writePermssion for <path-permission>"); + Log.w(TAG, "No readPermission or writePermssion for <path-permission>: " + + parser.getName() + " at " + mArchiveSourcePath + " " + + parser.getPositionDescription()); XmlUtils.skipCurrentTag(parser); continue; } @@ -2141,8 +2142,9 @@ public class PackageParser { } } else { if (!RIGID_PARSER) { - Log.w(TAG, "Problem in package " + mArchiveSourcePath + ":"); - Log.w(TAG, "No path, pathPrefix, or pathPattern for <path-permission>"); + Log.w(TAG, "No path, pathPrefix, or pathPattern for <path-permission>: " + + parser.getName() + " at " + mArchiveSourcePath + " " + + parser.getPositionDescription()); XmlUtils.skipCurrentTag(parser); continue; } @@ -2153,9 +2155,9 @@ public class PackageParser { } else { if (!RIGID_PARSER) { - Log.w(TAG, "Problem in package " + mArchiveSourcePath + ":"); Log.w(TAG, "Unknown element under <provider>: " - + parser.getName()); + + parser.getName() + " at " + mArchiveSourcePath + " " + + parser.getPositionDescription()); XmlUtils.skipCurrentTag(parser); continue; } @@ -2233,9 +2235,9 @@ public class PackageParser { } } else { if (!RIGID_PARSER) { - Log.w(TAG, "Problem in package " + mArchiveSourcePath + ":"); Log.w(TAG, "Unknown element under <service>: " - + parser.getName()); + + parser.getName() + " at " + mArchiveSourcePath + " " + + parser.getPositionDescription()); XmlUtils.skipCurrentTag(parser); continue; } @@ -2272,9 +2274,9 @@ public class PackageParser { } } else { if (!RIGID_PARSER) { - Log.w(TAG, "Problem in package " + mArchiveSourcePath + ":"); Log.w(TAG, "Unknown element under " + tag + ": " - + parser.getName()); + + parser.getName() + " at " + mArchiveSourcePath + " " + + parser.getPositionDescription()); XmlUtils.skipCurrentTag(parser); continue; } @@ -2330,8 +2332,9 @@ public class PackageParser { data.putFloat(name, v.getFloat()); } else { if (!RIGID_PARSER) { - Log.w(TAG, "Problem in package " + mArchiveSourcePath + ":"); - Log.w(TAG, "<meta-data> only supports string, integer, float, color, boolean, and resource reference types"); + Log.w(TAG, "<meta-data> only supports string, integer, float, color, boolean, and resource reference types: " + + parser.getName() + " at " + mArchiveSourcePath + " " + + parser.getPositionDescription()); } else { outError[0] = "<meta-data> only supports string, integer, float, color, boolean, and resource reference types"; data = null; @@ -2365,6 +2368,7 @@ public class PackageParser { com.android.internal.R.styleable.AndroidManifestIntentFilter_priority, 0); if (priority > 0 && isActivity && (flags&PARSE_IS_SYSTEM) == 0) { Log.w(TAG, "Activity with priority > 0, forcing to 0 at " + + mArchiveSourcePath + " " + parser.getPositionDescription()); priority = 0; } @@ -2462,8 +2466,9 @@ public class PackageParser { sa.recycle(); XmlUtils.skipCurrentTag(parser); } else if (!RIGID_PARSER) { - Log.w(TAG, "Problem in package " + mArchiveSourcePath + ":"); - Log.w(TAG, "Unknown element under <intent-filter>: " + parser.getName()); + Log.w(TAG, "Unknown element under <intent-filter>: " + + parser.getName() + " at " + mArchiveSourcePath + " " + + parser.getPositionDescription()); XmlUtils.skipCurrentTag(parser); } else { outError[0] = "Bad element under <intent-filter>: " + parser.getName(); diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java index 11c8b6f..66f5740 100644 --- a/core/java/android/hardware/Camera.java +++ b/core/java/android/hardware/Camera.java @@ -1281,7 +1281,11 @@ public class Camera { } /** - * Sets the scene mode. + * Sets the scene mode. Other parameters may be changed after changing + * scene mode. For example, flash and supported flash mode may be + * changed to "off" in night scene mode. After setting scene mode, + * applications should call getParameters to know if some parameters are + * changed. * * @param value SCENE_MODE_XXX string constants. */ diff --git a/core/java/android/pim/vcard/ContactStruct.java b/core/java/android/pim/vcard/ContactStruct.java index e87c796..b6a453a 100644 --- a/core/java/android/pim/vcard/ContactStruct.java +++ b/core/java/android/pim/vcard/ContactStruct.java @@ -25,8 +25,8 @@ import android.provider.ContactsContract; import android.provider.ContactsContract.Data; import android.provider.ContactsContract.Groups; import android.provider.ContactsContract.RawContacts; -import android.provider.ContactsContract.CommonDataKinds.Birthday; import android.provider.ContactsContract.CommonDataKinds.Email; +import android.provider.ContactsContract.CommonDataKinds.Event; import android.provider.ContactsContract.CommonDataKinds.GroupMembership; import android.provider.ContactsContract.CommonDataKinds.Im; import android.provider.ContactsContract.CommonDataKinds.Nickname; @@ -810,7 +810,8 @@ public class ContactStruct { } else if (propName.equals("NICKNAME") || propName.equals("X-NICKNAME")) { addNickName(propValue); } else if (propName.equals("SOUND")) { - if (Constants.ATTR_TYPE_X_IRMC_N.equals(paramMap.get(Constants.ATTR_TYPE))) { + Collection<String> typeCollection = paramMap.get(Constants.ATTR_TYPE); + if (typeCollection != null && typeCollection.contains(Constants.ATTR_TYPE_X_IRMC_N)) { handlePhoneticNameFromSound(propValueList); } else { // Ignore this field since Android cannot understand what it is. @@ -1316,9 +1317,10 @@ public class ContactStruct { if (!TextUtils.isEmpty(mBirthday)) { builder = ContentProviderOperation.newInsert(Data.CONTENT_URI); - builder.withValueBackReference(Birthday.RAW_CONTACT_ID, 0); - builder.withValue(Data.MIMETYPE, Birthday.CONTENT_ITEM_TYPE); - builder.withValue(Birthday.BIRTHDAY, mBirthday); + builder.withValueBackReference(Event.RAW_CONTACT_ID, 0); + builder.withValue(Data.MIMETYPE, Event.CONTENT_ITEM_TYPE); + builder.withValue(Event.START_DATE, mBirthday); + builder.withValue(Event.TYPE, Event.TYPE_BIRTHDAY); operationList.add(builder.build()); } diff --git a/core/java/android/pim/vcard/VCardComposer.java b/core/java/android/pim/vcard/VCardComposer.java index c943d85..7b75f4a 100644 --- a/core/java/android/pim/vcard/VCardComposer.java +++ b/core/java/android/pim/vcard/VCardComposer.java @@ -30,8 +30,8 @@ import android.provider.CallLog.Calls; import android.provider.ContactsContract.Contacts; import android.provider.ContactsContract.Data; import android.provider.ContactsContract.RawContacts; -import android.provider.ContactsContract.CommonDataKinds.Birthday; import android.provider.ContactsContract.CommonDataKinds.Email; +import android.provider.ContactsContract.CommonDataKinds.Event; import android.provider.ContactsContract.CommonDataKinds.Im; import android.provider.ContactsContract.CommonDataKinds.Nickname; import android.provider.ContactsContract.CommonDataKinds.Note; @@ -1301,12 +1301,16 @@ public class VCardComposer { private void appendBirthday(final StringBuilder builder, final Map<String, List<ContentValues>> contentValuesListMap) { final List<ContentValues> contentValuesList = contentValuesListMap - .get(Birthday.CONTENT_ITEM_TYPE); + .get(Event.CONTENT_ITEM_TYPE); if (contentValuesList != null && contentValuesList.size() > 0) { + Integer eventType = contentValuesList.get(0).getAsInteger(Event.TYPE); + if (eventType == null || !eventType.equals(Event.TYPE_BIRTHDAY)) { + return; + } // Theoretically, there must be only one birthday for each vCard data and // we are afraid of some parse error occuring in some devices, so // we emit only one birthday entry for now. - String birthday = contentValuesList.get(0).getAsString(Birthday.BIRTHDAY); + String birthday = contentValuesList.get(0).getAsString(Event.START_DATE); if (birthday != null) { birthday = birthday.trim(); } diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java index cebb75c..08a2a9f 100644 --- a/core/java/android/preference/Preference.java +++ b/core/java/android/preference/Preference.java @@ -102,7 +102,6 @@ public class Preference implements Comparable<Preference>, OnDependencyChangeLis private int mLayoutResId = com.android.internal.R.layout.preference; private int mWidgetLayoutResId; private boolean mHasSpecifiedLayout = false; - private View mLayoutView; private OnPreferenceChangeInternalListener mListener; @@ -337,7 +336,7 @@ public class Preference implements Comparable<Preference>, OnDependencyChangeLis if (!mHasSpecifiedLayout) { mHasSpecifiedLayout = true; } - mLayoutView = null; + mLayoutResId = layoutResId; } @@ -361,7 +360,6 @@ public class Preference implements Comparable<Preference>, OnDependencyChangeLis * @see #setLayoutResource(int) */ public void setWidgetLayoutResource(int widgetLayoutResId) { - mLayoutView = null; mWidgetLayoutResId = widgetLayoutResId; } @@ -389,10 +387,7 @@ public class Preference implements Comparable<Preference>, OnDependencyChangeLis */ public View getView(View convertView, ViewGroup parent) { if (convertView == null) { - if (mLayoutView == null) { - mLayoutView = onCreateView(parent); - } - convertView = mLayoutView; + convertView = onCreateView(parent); } onBindView(convertView); return convertView; diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java index 70a20d6..2e4bbab 100644 --- a/core/java/android/provider/ContactsContract.java +++ b/core/java/android/provider/ContactsContract.java @@ -1692,26 +1692,6 @@ public final class ContactsContract { } /** - * Common data definition for birthdays. - */ - public static final class Birthday implements DataColumnsWithJoins { - /** - * This utility class cannot be instantiated - */ - private Birthday() {} - - /** MIME type used when storing this in data table. */ - public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/birthday"; - - /** - * The birthday. This must be of the form YYYY-MM-DD or YYYY-MM-DDThh:mm:ss - * These are xs:date and xs:dateTime - * <P>Type: TEXT</P> - */ - public static final String BIRTHDAY = DATA1; - } - - /** * Common data definition for relations. */ public static final class Relation implements DataColumnsWithJoins, CommonColumns { @@ -1755,16 +1735,34 @@ public final class ContactsContract { private Event() {} /** MIME type used when storing this in data table. */ - public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/event"; + public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/contact_event"; public static final int TYPE_ANNIVERSARY = 1; public static final int TYPE_OTHER = 2; + public static final int TYPE_BIRTHDAY = 3; /** * The event start date as the user entered it. * <P>Type: TEXT</P> */ public static final String START_DATE = DATA; + + /** + * Return the string resource that best describes the given + * {@link #TYPE}. Will always return a valid resource. + */ + public static int getTypeResource(Integer type) { + if (type == null) { + return com.android.internal.R.string.eventTypeOther; + } + switch (type) { + case TYPE_ANNIVERSARY: + return com.android.internal.R.string.eventTypeAnniversary; + case TYPE_BIRTHDAY: return com.android.internal.R.string.eventTypeBirthday; + case TYPE_OTHER: return com.android.internal.R.string.eventTypeOther; + default: return com.android.internal.R.string.eventTypeOther; + } + } } /** @@ -2133,18 +2131,16 @@ public final class ContactsContract { } /** - * Helper methods to display FastTrack dialogs that allow users to pivot on + * Helper methods to display QuickContact dialogs that allow users to pivot on * a specific {@link Contacts} entry. - * - * @hide */ - public static final class FastTrack { + public static final class QuickContact { /** * Action used to trigger person pivot dialog. * @hide */ - public static final String ACTION_FAST_TRACK = - "com.android.contacts.action.FAST_TRACK"; + public static final String ACTION_QUICK_CONTACT = + "com.android.contacts.action.QUICK_CONTACT"; /** * Extra used to specify pivot dialog location in screen coordinates. @@ -2166,19 +2162,19 @@ public final class ContactsContract { public static final String EXTRA_EXCLUDE_MIMES = "exclude_mimes"; /** - * Small FastTrack mode, usually presented with minimal actions. + * Small QuickContact mode, usually presented with minimal actions. */ public static final int MODE_SMALL = 1; /** - * Medium FastTrack mode, includes actions and light summary describing + * Medium QuickContact mode, includes actions and light summary describing * the {@link Contacts} entry being shown. This may include social * status and presence details. */ public static final int MODE_MEDIUM = 2; /** - * Large FastTrack mode, includes actions and larger, card-like summary + * Large QuickContact mode, includes actions and larger, card-like summary * of the {@link Contacts} entry being shown. This may include detailed * information, such as a photo. */ @@ -2207,7 +2203,7 @@ public final class ContactsContract { * already viewing the contact details card, this can be used * to omit the details entry from the dialog. */ - public static void showFastTrack(Context context, View target, Uri lookupUri, int mode, + public static void showQuickContact(Context context, View target, Uri lookupUri, int mode, String[] excludeMimes) { // Find location and bounds of target view final int[] location = new int[2]; @@ -2220,7 +2216,7 @@ public final class ContactsContract { rect.bottom = rect.top + target.getHeight(); // Trigger with obtained rectangle - showFastTrack(context, rect, lookupUri, mode, excludeMimes); + showQuickContact(context, rect, lookupUri, mode, excludeMimes); } /** @@ -2246,14 +2242,15 @@ public final class ContactsContract { * already viewing the contact details card, this can be used * to omit the details entry from the dialog. */ - public static void showFastTrack(Context context, Rect target, Uri lookupUri, int mode, + public static void showQuickContact(Context context, Rect target, Uri lookupUri, int mode, String[] excludeMimes) { // Launch pivot dialog through intent for now - final Intent intent = new Intent(ACTION_FAST_TRACK); + final Intent intent = new Intent(ACTION_QUICK_CONTACT); intent.setData(lookupUri); intent.putExtra(EXTRA_TARGET_RECT, target); intent.putExtra(EXTRA_MODE, mode); intent.putExtra(EXTRA_EXCLUDE_MIMES, excludeMimes); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); context.startActivity(intent); } } diff --git a/core/java/android/provider/LiveFolders.java b/core/java/android/provider/LiveFolders.java index 19f361b..7856bab 100644 --- a/core/java/android/provider/LiveFolders.java +++ b/core/java/android/provider/LiveFolders.java @@ -40,12 +40,11 @@ import android.annotation.SdkConstant; * to retrieve the folder's content.</p> * * <h3>Setting up the live folder activity</h3> - * <p>The following code sample shows how to write an activity that creates a live fodler:</p> + * <p>The following code sample shows how to write an activity that creates a live folder:</p> * <pre> * public static class MyLiveFolder extends Activity { * public static final Uri CONTENT_URI = Uri.parse("content://my.app/live"); * - * &#064;Override * protected void onCreate(Bundle savedInstanceState) { * super.onCreate(savedInstanceState); * diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index f27902d..2ca17f6 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -464,7 +464,7 @@ public final class Settings { resolver.insert(uri, values); return true; } catch (SQLException e) { - Log.e(TAG, "Can't set key " + name + " in " + uri, e); + Log.w(TAG, "Can't set key " + name + " in " + uri, e); return false; } } @@ -501,7 +501,7 @@ public final class Settings { mValues.put(name, value); } catch (SQLException e) { // SQL error: return null, but don't cache it. - Log.e(TAG, "Can't get key " + name + " from " + mUri, e); + Log.w(TAG, "Can't get key " + name + " from " + mUri, e); } finally { if (c != null) c.close(); } @@ -3746,7 +3746,7 @@ public final class Settings { // The stored URL is bad... ignore it. } catch (IllegalArgumentException e) { // Column not found - Log.e(TAG, "Intent column not found", e); + Log.w(TAG, "Intent column not found", e); } } } finally { diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java index 4a5f431..d61b42f 100644 --- a/core/java/android/server/BluetoothA2dpService.java +++ b/core/java/android/server/BluetoothA2dpService.java @@ -112,6 +112,13 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub { Message msg = Message.obtain(mHandler, MESSAGE_CONNECT_TO, device); mHandler.sendMessageDelayed(msg, 6000); } + } else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) { + synchronized (this) { + if (mAudioDevices.containsKey(device)) { + int state = mAudioDevices.get(device); + handleSinkStateChange(device, state, BluetoothA2dp.STATE_DISCONNECTED); + } + } } } }; @@ -135,6 +142,7 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub { mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); mIntentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); mIntentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED); + mIntentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); mContext.registerReceiver(mReceiver, mIntentFilter); mAudioDevices = new HashMap<BluetoothDevice, Integer>(); @@ -333,10 +341,11 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub { return false; } String path = mBluetoothService.getObjectPathFromAddress(device.getAddress()); - if (path == null) { + Integer state = mAudioDevices.get(device); + if (path == null || state == null) { return false; } - switch (mAudioDevices.get(device)) { + switch (state.intValue()) { case BluetoothA2dp.STATE_CONNECTED: return true; case BluetoothA2dp.STATE_PLAYING: @@ -354,10 +363,11 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub { return false; } String path = mBluetoothService.getObjectPathFromAddress(device.getAddress()); - if (path == null) { + Integer state = mAudioDevices.get(device); + if (path == null || state == null) { return false; } - switch (mAudioDevices.get(device)) { + switch (state.intValue()) { case BluetoothA2dp.STATE_PLAYING: return true; case BluetoothA2dp.STATE_CONNECTED: diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java index 037e9d3..0152223 100644 --- a/core/java/android/server/BluetoothEventLoop.java +++ b/core/java/android/server/BluetoothEventLoop.java @@ -403,9 +403,13 @@ class BluetoothEventLoop { mBluetoothService.cancelPairingUserInput(address); return null; } - // Set state to BONDING, for incoming connections it will be set here. - // For outgoing connections, it gets set when call createBond. - mBluetoothService.getBondState().setBondState(address, BluetoothDevice.BOND_BONDING); + // Set state to BONDING. For incoming connections it will be set here. + // For outgoing connections, it gets set when we call createBond. + // Also set it only when the state is not already Bonded, we can sometimes + // get an authorization request from the remote end if it doesn't have the link key + // while we still have it. + if (mBluetoothService.getBondState().getBondState(address) != BluetoothDevice.BOND_BONDED) + mBluetoothService.getBondState().setBondState(address, BluetoothDevice.BOND_BONDING); return address; } diff --git a/core/java/android/text/method/QwertyKeyListener.java b/core/java/android/text/method/QwertyKeyListener.java index f736f85..2e76470 100644 --- a/core/java/android/text/method/QwertyKeyListener.java +++ b/core/java/android/text/method/QwertyKeyListener.java @@ -405,12 +405,13 @@ public class QwertyKeyListener extends BaseKeyListener { PICKER_SETS.put('C', "\u00C7\u0106\u010C"); PICKER_SETS.put('D', "\u010E"); PICKER_SETS.put('E', "\u00C8\u00C9\u00CA\u00CB\u0118\u011A\u0112"); + PICKER_SETS.put('G', "\u011E"); PICKER_SETS.put('L', "\u0141"); PICKER_SETS.put('I', "\u00CC\u00CD\u00CE\u00CF\u012A\u0130"); PICKER_SETS.put('N', "\u00D1\u0143\u0147"); PICKER_SETS.put('O', "\u00D8\u0152\u00D5\u00D2\u00D3\u00D4\u00D6\u014C"); PICKER_SETS.put('R', "\u0158"); - PICKER_SETS.put('S', "\u015A\u0160"); + PICKER_SETS.put('S', "\u015A\u0160\u015E"); PICKER_SETS.put('T', "\u0164"); PICKER_SETS.put('U', "\u00D9\u00DA\u00DB\u00DC\u016E\u016A"); PICKER_SETS.put('Y', "\u00DD\u0178"); @@ -419,12 +420,13 @@ public class QwertyKeyListener extends BaseKeyListener { PICKER_SETS.put('c', "\u00E7\u0107\u010D"); PICKER_SETS.put('d', "\u010F"); PICKER_SETS.put('e', "\u00E8\u00E9\u00EA\u00EB\u0119\u011B\u0113"); + PICKER_SETS.put('g', "\u011F"); PICKER_SETS.put('i', "\u00EC\u00ED\u00EE\u00EF\u012B\u0131"); PICKER_SETS.put('l', "\u0142"); PICKER_SETS.put('n', "\u00F1\u0144\u0148"); PICKER_SETS.put('o', "\u00F8\u0153\u00F5\u00F2\u00F3\u00F4\u00F6\u014D"); PICKER_SETS.put('r', "\u0159"); - PICKER_SETS.put('s', "\u00A7\u00DF\u015B\u0161"); + PICKER_SETS.put('s', "\u00A7\u00DF\u015B\u0161\u015F"); PICKER_SETS.put('t', "\u0165"); PICKER_SETS.put('u', "\u00F9\u00FA\u00FB\u00FC\u016F\u016B"); PICKER_SETS.put('y', "\u00FD\u00FF"); diff --git a/core/java/android/webkit/HTML5VideoViewProxy.java b/core/java/android/webkit/HTML5VideoViewProxy.java index 8b783e8..b7a9065 100644 --- a/core/java/android/webkit/HTML5VideoViewProxy.java +++ b/core/java/android/webkit/HTML5VideoViewProxy.java @@ -39,10 +39,8 @@ import android.view.MotionEvent; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; -import android.webkit.ViewManager.ChildView; import android.widget.AbsoluteLayout; import android.widget.FrameLayout; -import android.widget.ImageView; import android.widget.MediaController; import android.widget.VideoView; @@ -56,20 +54,22 @@ import java.util.Map; */ class HTML5VideoViewProxy extends Handler implements MediaPlayer.OnPreparedListener, - MediaPlayer.OnCompletionListener { + MediaPlayer.OnCompletionListener, + MediaPlayer.OnErrorListener { // Logging tag. private static final String LOGTAG = "HTML5VideoViewProxy"; // Message Ids for WebCore thread -> UI thread communication. - private static final int INIT = 100; - private static final int PLAY = 101; - private static final int SET_POSTER = 102; - private static final int SEEK = 103; - private static final int PAUSE = 104; + private static final int PLAY = 100; + private static final int SEEK = 101; + private static final int PAUSE = 102; + private static final int ERROR = 103; + private static final int LOAD_DEFAULT_POSTER = 104; // Message Ids to be handled on the WebCore thread private static final int PREPARED = 200; private static final int ENDED = 201; + private static final int POSTER_FETCHED = 202; // The C++ MediaPlayerPrivateAndroid object. int mNativePointer; @@ -77,10 +77,9 @@ class HTML5VideoViewProxy extends Handler private Handler mWebCoreHandler; // The WebView instance that created this view. private WebView mWebView; - // The ChildView instance used by the ViewManager. - private ChildView mChildView; // The poster image to be shown when the video is not playing. - private ImageView mPosterView; + // This ref prevents the bitmap from being GC'ed. + private Bitmap mPoster; // The poster downloader. private PosterDownloader mPosterDownloader; // The seek position. @@ -138,6 +137,7 @@ class HTML5VideoViewProxy extends Handler mVideoView.setVideoURI(Uri.parse(url)); mVideoView.setOnCompletionListener(proxy); mVideoView.setOnPreparedListener(proxy); + mVideoView.setOnErrorListener(proxy); mVideoView.seekTo(time); mLayout.addView(mVideoView, layoutParams); mProgressView = client.getVideoLoadingProgressView(); @@ -163,11 +163,12 @@ class HTML5VideoViewProxy extends Handler } public static void onPrepared() { - if (mProgressView != null) { - mProgressView.setVisibility(View.GONE); - mLayout.removeView(mProgressView); - mProgressView = null; + if (mProgressView == null || mLayout == null) { + return; } + mProgressView.setVisibility(View.GONE); + mLayout.removeView(mProgressView); + mProgressView = null; } } @@ -189,6 +190,12 @@ class HTML5VideoViewProxy extends Handler playbackEnded(); } + // MediaPlayer.OnErrorListener + public boolean onError(MediaPlayer mp, int what, int extra) { + sendMessage(obtainMessage(ERROR)); + return false; + } + public void playbackEnded() { Message msg = Message.obtain(mWebCoreHandler, ENDED); mWebCoreHandler.sendMessage(msg); @@ -199,18 +206,6 @@ class HTML5VideoViewProxy extends Handler public void handleMessage(Message msg) { // This executes on the UI thread. switch (msg.what) { - case INIT: { - mPosterView = new ImageView(mWebView.getContext()); - WebChromeClient client = mWebView.getWebChromeClient(); - if (client != null) { - Bitmap poster = client.getDefaultVideoPoster(); - if (poster != null) { - mPosterView.setImageBitmap(poster); - } - } - mChildView.mView = mPosterView; - break; - } case PLAY: { String url = (String) msg.obj; WebChromeClient client = mWebView.getWebChromeClient(); @@ -219,11 +214,6 @@ class HTML5VideoViewProxy extends Handler } break; } - case SET_POSTER: { - Bitmap poster = (Bitmap) msg.obj; - mPosterView.setImageBitmap(poster); - break; - } case SEEK: { Integer time = (Integer) msg.obj; mSeekPosition = time; @@ -234,6 +224,20 @@ class HTML5VideoViewProxy extends Handler VideoPlayer.pause(this); break; } + case ERROR: { + WebChromeClient client = mWebView.getWebChromeClient(); + if (client != null) { + client.onHideCustomView(); + } + break; + } + case LOAD_DEFAULT_POSTER: { + WebChromeClient client = mWebView.getWebChromeClient(); + if (client != null) { + doSetPoster(client.getDefaultVideoPoster()); + } + break; + } } } @@ -302,9 +306,7 @@ class HTML5VideoViewProxy extends Handler if (mPosterBytes.size() > 0) { Bitmap poster = BitmapFactory.decodeByteArray( mPosterBytes.toByteArray(), 0, mPosterBytes.size()); - if (poster != null) { - mProxy.doSetPoster(poster); - } + mProxy.doSetPoster(poster); } cleanup(); } else if (mStatusCode >= 300 && mStatusCode < 400) { @@ -401,6 +403,10 @@ class HTML5VideoViewProxy extends Handler case ENDED: nativeOnEnded(mNativePointer); break; + case POSTER_FETCHED: + Bitmap poster = (Bitmap) msg.obj; + nativeOnPosterFetched(poster, mNativePointer); + break; } } }; @@ -410,10 +416,11 @@ class HTML5VideoViewProxy extends Handler if (poster == null) { return; } - // Send the bitmap over to the UI thread. - Message message = obtainMessage(SET_POSTER); - message.obj = poster; - sendMessage(message); + // Save a ref to the bitmap and send it over to the WebCore thread. + mPoster = poster; + Message msg = Message.obtain(mWebCoreHandler, POSTER_FETCHED); + msg.obj = poster; + mWebCoreHandler.sendMessage(msg); } public Context getContext() { @@ -453,38 +460,15 @@ class HTML5VideoViewProxy extends Handler } /** - * Create the child view that will cary the poster. + * Tear down this proxy object. */ - public void createView() { - mChildView = mWebView.mViewManager.createView(); - sendMessage(obtainMessage(INIT)); - } - - /** - * Attach the poster view. - * @param x, y are the screen coordinates where the poster should be hung. - * @param width, height denote the size of the poster. - */ - public void attachView(int x, int y, int width, int height) { - if (mChildView == null) { - return; - } - mChildView.attachView(x, y, width, height); - } - - /** - * Remove the child view and, thus, the poster. - */ - public void removeView() { - if (mChildView == null) { - return; - } - mChildView.removeView(); + public void teardown() { // This is called by the C++ MediaPlayerPrivate dtor. // Cancel any active poster download. if (mPosterDownloader != null) { mPosterDownloader.cancelAndReleaseQueue(); } + mNativePointer = 0; } /** @@ -493,6 +477,8 @@ class HTML5VideoViewProxy extends Handler */ public void loadPoster(String url) { if (url == null) { + Message message = obtainMessage(LOAD_DEFAULT_POSTER); + sendMessage(message); return; } // Cancel any active poster download. @@ -516,4 +502,5 @@ class HTML5VideoViewProxy extends Handler private native void nativeOnPrepared(int duration, int width, int height, int nativePointer); private native void nativeOnEnded(int nativePointer); + private native void nativeOnPosterFetched(Bitmap poster, int nativePointer); } diff --git a/core/java/android/webkit/PluginManager.java b/core/java/android/webkit/PluginManager.java index 766bd75..edba446 100644 --- a/core/java/android/webkit/PluginManager.java +++ b/core/java/android/webkit/PluginManager.java @@ -65,6 +65,15 @@ public class PluginManager { private ArrayList<PackageInfo> mPackageInfoCache; + // Only plugin matches one of the signatures in the list can be loaded + // inside the WebView process + private static final String SIGNATURE_1 = "308204a830820390a003020102020900936eacbe07f201df300d06092a864886f70d0101050500308194310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d301e170d3038303232393031333334365a170d3335303731373031333334365a308194310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d30820120300d06092a864886f70d01010105000382010d00308201080282010100d6931904dec60b24b1edc762e0d9d8253e3ecd6ceb1de2ff068ca8e8bca8cd6bd3786ea70aa76ce60ebb0f993559ffd93e77a943e7e83d4b64b8e4fea2d3e656f1e267a81bbfb230b578c20443be4c7218b846f5211586f038a14e89c2be387f8ebecf8fcac3da1ee330c9ea93d0a7c3dc4af350220d50080732e0809717ee6a053359e6a694ec2cb3f284a0a466c87a94d83b31093a67372e2f6412c06e6d42f15818dffe0381cc0cd444da6cddc3b82458194801b32564134fbfde98c9287748dbf5676a540d8154c8bbca07b9e247553311c46b9af76fdeeccc8e69e7c8a2d08e782620943f99727d3c04fe72991d99df9bae38a0b2177fa31d5b6afee91f020103a381fc3081f9301d0603551d0e04160414485900563d272c46ae118605a47419ac09ca8c113081c90603551d230481c13081be8014485900563d272c46ae118605a47419ac09ca8c11a1819aa48197308194310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d820900936eacbe07f201df300c0603551d13040530030101ff300d06092a864886f70d010105050003820101007aaf968ceb50c441055118d0daabaf015b8a765a27a715a2c2b44f221415ffdace03095abfa42df70708726c2069e5c36eddae0400be29452c084bc27eb6a17eac9dbe182c204eb15311f455d824b656dbe4dc2240912d7586fe88951d01a8feb5ae5a4260535df83431052422468c36e22c2a5ef994d61dd7306ae4c9f6951ba3c12f1d1914ddc61f1a62da2df827f603fea5603b2c540dbd7c019c36bab29a4271c117df523cdbc5f3817a49e0efa60cbd7f74177e7a4f193d43f4220772666e4c4d83e1bd5a86087cf34f2dec21e245ca6c2bb016e683638050d2c430eea7c26a1c49d3760a58ab7f1a82cc938b4831384324bd0401fa12163a50570e684d"; + private static final String SIGNATURE_2 = "308204c5308203ada003020102020900d7cb412f75f4887e300d06092a864886f70d010105050030819d310b3009060355040613025553311330110603550408130a43616c69666f726e69613111300f0603550407130853616e204a6f736531233021060355040a131a41646f62652053797374656d7320496e636f72706f7261746564311c301a060355040b1313496e666f726d6174696f6e2053797374656d73312330210603550403131a41646f62652053797374656d7320496e636f72706f7261746564301e170d3039313030313030323331345a170d3337303231363030323331345a30819d310b3009060355040613025553311330110603550408130a43616c69666f726e69613111300f0603550407130853616e204a6f736531233021060355040a131a41646f62652053797374656d7320496e636f72706f7261746564311c301a060355040b1313496e666f726d6174696f6e2053797374656d73312330210603550403131a41646f62652053797374656d7320496e636f72706f726174656430820120300d06092a864886f70d01010105000382010d0030820108028201010099724f3e05bbd78843794f357776e04b340e13cb1c9ccb3044865180d7d8fec8166c5bbd876da8b80aa71eb6ba3d4d3455c9a8de162d24a25c4c1cd04c9523affd06a279fc8f0d018f242486bdbb2dbfbf6fcb21ed567879091928b876f7ccebc7bccef157366ebe74e33ae1d7e9373091adab8327482154afc0693a549522f8c796dd84d16e24bb221f5dbb809ca56dd2b6e799c5fa06b6d9c5c09ada54ea4c5db1523a9794ed22a3889e5e05b29f8ee0a8d61efe07ae28f65dece2ff7edc5b1416d7c7aad7f0d35e8f4a4b964dbf50ae9aa6d620157770d974131b3e7e3abd6d163d65758e2f0822db9c88598b9db6263d963d13942c91fc5efe34fc1e06e3020103a382010630820102301d0603551d0e041604145af418e419a639e1657db960996364a37ef20d403081d20603551d230481ca3081c780145af418e419a639e1657db960996364a37ef20d40a181a3a481a030819d310b3009060355040613025553311330110603550408130a43616c69666f726e69613111300f0603550407130853616e204a6f736531233021060355040a131a41646f62652053797374656d7320496e636f72706f7261746564311c301a060355040b1313496e666f726d6174696f6e2053797374656d73312330210603550403131a41646f62652053797374656d7320496e636f72706f7261746564820900d7cb412f75f4887e300c0603551d13040530030101ff300d06092a864886f70d0101050500038201010076c2a11fe303359689c2ebc7b2c398eff8c3f9ad545cdbac75df63bf7b5395b6988d1842d6aa1556d595b5692e08224d667a4c9c438f05e74906c53dd8016dde7004068866f01846365efd146e9bfaa48c9ecf657f87b97c757da11f225c4a24177bf2d7188e6cce2a70a1e8a841a14471eb51457398b8a0addd8b6c8c1538ca8f1e40b4d8b960009ea22c188d28924813d2c0b4a4d334b7cf05507e1fcf0a06fe946c7ffc435e173af6fc3e3400643710acc806f830a14788291d46f2feed9fb5c70423ca747ed1572d752894ac1f19f93989766308579393fabb43649aa8806a313b1ab9a50922a44c2467b9062037f2da0d484d9ffd8fe628eeea629ba637"; + + private static final Signature[] SIGNATURES = new Signature[] { + new Signature(SIGNATURE_1), new Signature(SIGNATURE_2) + }; + private PluginManager(Context context) { mContext = context; mPackageInfoCache = new ArrayList<PackageInfo>(); @@ -148,9 +157,12 @@ public class PluginManager { } boolean signatureMatch = false; for (Signature signature : signatures) { - // TODO: check signature against Google provided one - signatureMatch = true; - break; + for (int i = 0; i < SIGNATURES.length; i++) { + if (SIGNATURES[i].equals(signature)) { + signatureMatch = true; + break; + } + } } if (!signatureMatch) { continue; diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 50358c2..4bc1a0e 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -2863,17 +2863,31 @@ public class WebView extends AbsoluteLayout invalidate(); if (mNeedToAdjustWebTextView) { mNeedToAdjustWebTextView = false; - mWebTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, - contentToViewDimension( - nativeFocusCandidateTextSize())); - Rect bounds = nativeFocusCandidateNodeBounds(); - Rect vBox = contentToViewRect(bounds); - mWebTextView.setRect(vBox.left, vBox.top, vBox.width(), - vBox.height()); - // If it is a password field, start drawing the - // WebTextView once again. - if (nativeFocusCandidateIsPassword()) { - mWebTextView.setInPassword(true); + Rect contentBounds = nativeFocusCandidateNodeBounds(); + Rect vBox = contentToViewRect(contentBounds); + Rect visibleRect = new Rect(); + calcOurVisibleRect(visibleRect); + if (visibleRect.contains(vBox)) { + // As a result of the zoom, the textfield is now on + // screen. Place the WebTextView in its new place, + // accounting for our new scroll/zoom values. + mWebTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, + contentToViewDimension( + nativeFocusCandidateTextSize())); + mWebTextView.setRect(vBox.left, vBox.top, vBox.width(), + vBox.height()); + // If it is a password field, start drawing the + // WebTextView once again. + if (nativeFocusCandidateIsPassword()) { + mWebTextView.setInPassword(true); + } + } else { + // The textfield is now off screen. The user probably + // was not zooming to see the textfield better. Remove + // the WebTextView. If the user types a key, and the + // textfield is still in focus, we will reconstruct + // the WebTextView and scroll it back on screen. + mWebTextView.remove(); } } } @@ -3857,11 +3871,25 @@ public class WebView extends AbsoluteLayout if (mSnapScrollMode == SNAP_X || mSnapScrollMode == SNAP_X_LOCK) { - scrollBy(deltaX, 0); + if (deltaX == 0) { + // keep the scrollbar on the screen even there is no + // scroll + awakenScrollBars(ViewConfiguration + .getScrollDefaultDelay(), false); + } else { + scrollBy(deltaX, 0); + } mLastTouchX = x; } else if (mSnapScrollMode == SNAP_Y || mSnapScrollMode == SNAP_Y_LOCK) { - scrollBy(0, deltaY); + if (deltaY == 0) { + // keep the scrollbar on the screen even there is no + // scroll + awakenScrollBars(ViewConfiguration + .getScrollDefaultDelay(), false); + } else { + scrollBy(0, deltaY); + } mLastTouchY = y; } else { scrollBy(deltaX, deltaY); @@ -3886,6 +3914,9 @@ public class WebView extends AbsoluteLayout } if (done) { + // keep the scrollbar on the screen even there is no scroll + awakenScrollBars(ViewConfiguration.getScrollDefaultDelay(), + false); // return false to indicate that we can't pan out of the // view space return false; diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java index 953dd92..1449ea5 100644 --- a/core/java/android/widget/AutoCompleteTextView.java +++ b/core/java/android/widget/AutoCompleteTextView.java @@ -82,6 +82,8 @@ import com.android.internal.R; * @attr ref android.R.styleable#AutoCompleteTextView_dropDownAnchor * @attr ref android.R.styleable#AutoCompleteTextView_dropDownWidth * @attr ref android.R.styleable#AutoCompleteTextView_dropDownHeight + * @attr ref android.R.styleable#AutoCompleteTextView_dropDownVerticalOffset + * @attr ref android.R.styleable#AutoCompleteTextView_dropDownHorizontalOffset */ public class AutoCompleteTextView extends EditText implements Filter.FilterListener { static final boolean DEBUG = false; @@ -1153,7 +1155,7 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe heightSpec = mDropDownHeight; } - mPopup.setOutsideTouchable(mForceIgnoreOutsideTouch ? false : !mDropDownAlwaysVisible); + mPopup.setOutsideTouchable(!mForceIgnoreOutsideTouch && !mDropDownAlwaysVisible); mPopup.update(getDropDownAnchorView(), mDropDownHorizontalOffset, mDropDownVerticalOffset, widthSpec, heightSpec); @@ -1183,8 +1185,8 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe // use outside touchable to dismiss drop down when touching outside of it, so // only set this if the dropdown is not always visible - mPopup.setOutsideTouchable(mForceIgnoreOutsideTouch ? false : !mDropDownAlwaysVisible); - mPopup.setTouchInterceptor(new PopupTouchIntercepter()); + mPopup.setOutsideTouchable(!mForceIgnoreOutsideTouch && !mDropDownAlwaysVisible); + mPopup.setTouchInterceptor(new PopupTouchInterceptor()); mPopup.showAsDropDown(getDropDownAnchorView(), mDropDownHorizontalOffset, mDropDownVerticalOffset); mDropDownList.setSelection(ListView.INVALID_POSITION); @@ -1408,9 +1410,10 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe } } - private class PopupTouchIntercepter implements OnTouchListener { + private class PopupTouchInterceptor implements OnTouchListener { public boolean onTouch(View v, MotionEvent event) { - if (event.getAction() == MotionEvent.ACTION_DOWN) { + if (event.getAction() == MotionEvent.ACTION_DOWN && + mPopup != null && mPopup.isShowing()) { mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); showDropDown(); } diff --git a/core/java/android/widget/QuickContactBadge.java b/core/java/android/widget/QuickContactBadge.java index b550d69..8019f14 100644 --- a/core/java/android/widget/QuickContactBadge.java +++ b/core/java/android/widget/QuickContactBadge.java @@ -25,7 +25,7 @@ import android.database.Cursor; import android.graphics.drawable.Drawable; import android.net.Uri; import android.provider.ContactsContract.Contacts; -import android.provider.ContactsContract.FastTrack; +import android.provider.ContactsContract.QuickContact; import android.provider.ContactsContract.Intents; import android.provider.ContactsContract.PhoneLookup; import android.provider.ContactsContract.RawContacts; @@ -88,7 +88,7 @@ public class QuickContactBadge extends ImageView implements OnClickListener { com.android.internal.R.styleable.QuickContactBadge, defStyle, 0); mMode = a.getInt(com.android.internal.R.styleable.QuickContactBadge_quickContactWindowSize, - FastTrack.MODE_MEDIUM); + QuickContact.MODE_MEDIUM); a.recycle(); @@ -103,6 +103,15 @@ public class QuickContactBadge extends ImageView implements OnClickListener { } /** + * Set the QuickContact window mode. Options are {@link QuickContact#MODE_SMALL}, + * {@link QuickContact#MODE_MEDIUM}, {@link QuickContact#MODE_LARGE}. + * @param size + */ + public void setMode(int size) { + mMode = size; + } + + /** * Assign the contact uri that this QuickContactBadge should be associated * with. Note that this is only used for displaying the QuickContact window and * won't bind the contact's photo for you. @@ -199,7 +208,7 @@ public class QuickContactBadge extends ImageView implements OnClickListener { } private void trigger(Uri lookupUri) { - FastTrack.showFastTrack(getContext(), this, lookupUri, mMode, mExcludeMimes); + QuickContact.showQuickContact(getContext(), this, lookupUri, mMode, mExcludeMimes); } private class QueryHandler extends AsyncQueryHandler { diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 7a8a3be..4b26b8f 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -2988,7 +2988,10 @@ public final class BatteryStatsImpl extends BatteryStats { if (mBackupFile.exists()) { mBackupFile.delete(); } - mFile.renameTo(mBackupFile); + if (!mFile.renameTo(mBackupFile)) { + Log.w("BatteryStats", "Failed to back up file before writing new stats"); + return; + } } try { @@ -3003,8 +3006,14 @@ public final class BatteryStatsImpl extends BatteryStats { mBackupFile.delete(); mLastWriteTime = SystemClock.elapsedRealtime(); + return; } catch (IOException e) { - Log.e("BatteryStats", "Error writing battery statistics", e); + Log.w("BatteryStats", "Error writing battery statistics", e); + } + if (mFile.exists()) { + if (!mFile.delete()) { + Log.w(TAG, "Failed to delete mangled file " + mFile); + } } } |