diff options
Diffstat (limited to 'core/java/android')
70 files changed, 882 insertions, 1163 deletions
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index e8d08b8..a7099d4 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -466,8 +466,9 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM String resultData = data.readString(); Bundle resultExtras = data.readBundle(); boolean resultAbort = data.readInt() != 0; + int intentFlags = data.readInt(); if (who != null) { - finishReceiver(who, resultCode, resultData, resultExtras, resultAbort); + finishReceiver(who, resultCode, resultData, resultExtras, resultAbort, intentFlags); } reply.writeNoException(); return true; @@ -2370,6 +2371,15 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM reply.writeNoException(); return true; } + + case NOTIFY_CLEARTEXT_NETWORK_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + final int uid = data.readInt(); + final byte[] firstPacket = data.createByteArray(); + notifyCleartextNetwork(uid, firstPacket); + reply.writeNoException(); + return true; + } } return super.onTransact(code, data, reply, flags); @@ -2848,7 +2858,8 @@ class ActivityManagerProxy implements IActivityManager data.recycle(); reply.recycle(); } - public void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map, boolean abortBroadcast) throws RemoteException + public void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map, + boolean abortBroadcast, int flags) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); @@ -2858,6 +2869,7 @@ class ActivityManagerProxy implements IActivityManager data.writeString(resultData); data.writeBundle(map); data.writeInt(abortBroadcast ? 1 : 0); + data.writeInt(flags); mRemote.transact(FINISH_RECEIVER_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY); reply.readException(); data.recycle(); @@ -5476,5 +5488,18 @@ class ActivityManagerProxy implements IActivityManager reply.recycle(); } + @Override + public void notifyCleartextNetwork(int uid, byte[] firstPacket) throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeInt(uid); + data.writeByteArray(firstPacket); + mRemote.transact(NOTIFY_CLEARTEXT_NETWORK_TRANSACTION, data, reply, 0); + reply.readException(); + data.recycle(); + reply.recycle(); + } + private IBinder mRemote; } diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index f2be45c..fb2bcd0 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -374,7 +374,7 @@ public final class ActivityThread { public ReceiverData(Intent intent, int resultCode, String resultData, Bundle resultExtras, boolean ordered, boolean sticky, IBinder token, int sendingUser) { super(resultCode, resultData, resultExtras, TYPE_COMPONENT, ordered, sticky, - token, sendingUser); + token, sendingUser, intent.getFlags()); this.intent = intent; } @@ -1086,8 +1086,7 @@ public final class ActivityThread { WindowManagerGlobal.getInstance().dumpGfxInfo(fd); } - @Override - public void dumpDbInfo(FileDescriptor fd, String[] args) { + private void dumpDatabaseInfo(FileDescriptor fd, String[] args) { PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd)); PrintWriterPrinter printer = new PrintWriterPrinter(pw); SQLiteDebug.dump(printer, args); @@ -1095,6 +1094,22 @@ public final class ActivityThread { } @Override + public void dumpDbInfo(final FileDescriptor fd, final String[] args) { + if (mSystemThread) { + // Ensure this invocation is asynchronous to prevent + // writer waiting due to buffer cannot be consumed. + AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() { + @Override + public void run() { + dumpDatabaseInfo(fd, args); + } + }); + } else { + dumpDatabaseInfo(fd, args); + } + } + + @Override public void unstableProviderDied(IBinder provider) { sendMessage(H.UNSTABLE_PROVIDER_DIED, provider); } @@ -1178,9 +1193,17 @@ public final class ActivityThread { sendMessage(H.BACKGROUND_VISIBLE_BEHIND_CHANGED, token, visible ? 1 : 0); } + @Override public void scheduleEnterAnimationComplete(IBinder token) { sendMessage(H.ENTER_ANIMATION_COMPLETE, token); } + + @Override + public void notifyCleartextNetwork(byte[] firstPacket) { + if (StrictMode.vmCleartextNetworkEnabled()) { + StrictMode.onCleartextNetworkDetected(firstPacket); + } + } } private class H extends Handler { @@ -4199,22 +4222,24 @@ public final class ActivityThread { final void handleDispatchPackageBroadcast(int cmd, String[] packages) { boolean hasPkgInfo = false; if (packages != null) { - for (int i=packages.length-1; i>=0; i--) { - //Slog.i(TAG, "Cleaning old package: " + packages[i]); - if (!hasPkgInfo) { - WeakReference<LoadedApk> ref; - ref = mPackages.get(packages[i]); - if (ref != null && ref.get() != null) { - hasPkgInfo = true; - } else { - ref = mResourcePackages.get(packages[i]); + synchronized (mResourcesManager) { + for (int i=packages.length-1; i>=0; i--) { + //Slog.i(TAG, "Cleaning old package: " + packages[i]); + if (!hasPkgInfo) { + WeakReference<LoadedApk> ref; + ref = mPackages.get(packages[i]); if (ref != null && ref.get() != null) { hasPkgInfo = true; + } else { + ref = mResourcePackages.get(packages[i]); + if (ref != null && ref.get() != null) { + hasPkgInfo = true; + } } } + mPackages.remove(packages[i]); + mResourcePackages.remove(packages[i]); } - mPackages.remove(packages[i]); - mResourcePackages.remove(packages[i]); } } ApplicationPackageManager.handlePackageBroadcast(cmd, packages, @@ -4517,6 +4542,10 @@ public final class ActivityThread { if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) { dalvik.system.VMRuntime.getRuntime().clearGrowthLimit(); + } else { + // Small heap, clamp to the current growth limit and let the heap release + // pages after the growth limit to the non growth limit capacity. b/18387825 + dalvik.system.VMRuntime.getRuntime().clampGrowthLimit(); } // Allow disk access during application and provider setup. This could diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java index d1b77b9..eb3ddb2 100644 --- a/core/java/android/app/ApplicationThreadNative.java +++ b/core/java/android/app/ApplicationThreadNative.java @@ -670,6 +670,15 @@ public abstract class ApplicationThreadNative extends Binder reply.writeNoException(); return true; } + + case NOTIFY_CLEARTEXT_NETWORK_TRANSACTION: + { + data.enforceInterface(IApplicationThread.descriptor); + final byte[] firstPacket = data.createByteArray(); + notifyCleartextNetwork(firstPacket); + reply.writeNoException(); + return true; + } } return super.onTransact(code, data, reply, flags); @@ -1350,4 +1359,13 @@ class ApplicationThreadProxy implements IApplicationThread { mRemote.transact(ENTER_ANIMATION_COMPLETE_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); data.recycle(); } + + @Override + public void notifyCleartextNetwork(byte[] firstPacket) throws RemoteException { + Parcel data = Parcel.obtain(); + data.writeInterfaceToken(IApplicationThread.descriptor); + data.writeByteArray(firstPacket); + mRemote.transact(NOTIFY_CLEARTEXT_NETWORK_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); + data.recycle(); + } } diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java index af45731..ab28d95 100644 --- a/core/java/android/app/Fragment.java +++ b/core/java/android/app/Fragment.java @@ -219,8 +219,8 @@ final class FragmentState implements Parcelable { * state of its view hierarchy has been restored. * <li> {@link #onStart} makes the fragment visible to the user (based on its * containing activity being started). - * <li> {@link #onResume} makes the fragment interacting with the user (based on its - * containing activity being resumed). + * <li> {@link #onResume} makes the fragment begin interacting with the user + * (based on its containing activity being resumed). * </ol> * * <p>As a fragment is no longer being used, it goes through a reverse @@ -564,7 +564,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene * and later retrieved by the Fragment with {@link #getArguments}. * * <p>Applications should generally not implement a constructor. The - * first place application code an run where the fragment is ready to + * first place application code can run where the fragment is ready to * be used is in {@link #onAttach(Activity)}, the point where the fragment * is actually associated with its activity. Some applications may also * want to implement {@link #onInflate} to retrieve attributes from a @@ -720,8 +720,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene } /** - * Return the arguments supplied when the fragment was instantiated, - * if any. + * Return the arguments supplied to {@link #setArguments}, if any. */ final public Bundle getArguments() { return mArguments; diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java index fc761fe..ccceef4 100644 --- a/core/java/android/app/FragmentManager.java +++ b/core/java/android/app/FragmentManager.java @@ -70,7 +70,7 @@ public abstract class FragmentManager { * with {@link FragmentTransaction#addToBackStack(String) * FragmentTransaction.addToBackStack()}. Entries can later be * retrieved with {@link FragmentManager#getBackStackEntryAt(int) - * FragmentManager.getBackStackEntry()}. + * FragmentManager.getBackStackEntryAt()}. * * <p>Note that you should never hold on to a BackStackEntry object; * the identifier as returned by {@link #getId} is the only thing that @@ -260,7 +260,7 @@ public abstract class FragmentManager { /** * Return the BackStackEntry at index <var>index</var> in the back stack; - * entries start index 0 being the bottom of the stack. + * where the item on the bottom of the stack has index 0. */ public abstract BackStackEntry getBackStackEntryAt(int index); diff --git a/core/java/android/app/FragmentTransaction.java b/core/java/android/app/FragmentTransaction.java index 25cd3cc..dc7075c 100644 --- a/core/java/android/app/FragmentTransaction.java +++ b/core/java/android/app/FragmentTransaction.java @@ -26,7 +26,7 @@ public abstract class FragmentTransaction { /** * Add a fragment to the activity state. This fragment may optionally * also have its view (if {@link Fragment#onCreateView Fragment.onCreateView} - * returns non-null) into a container view of the activity. + * returns non-null) inserted into a container view of the activity. * * @param containerViewId Optional identifier of the container this fragment is * to be placed in. If 0, it will not be placed in a container. diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index e505d69..70c14c6 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -106,7 +106,8 @@ public interface IActivityManager extends IInterface { String resultData, Bundle map, String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) throws RemoteException; public void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) throws RemoteException; - public void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map, boolean abortBroadcast) throws RemoteException; + public void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map, + boolean abortBroadcast, int flags) throws RemoteException; public void attachApplication(IApplicationThread app) throws RemoteException; public void activityResumed(IBinder token) throws RemoteException; public void activityIdle(IBinder token, Configuration config, @@ -470,6 +471,7 @@ public interface IActivityManager extends IInterface { public void notifyEnterAnimationComplete(IBinder token) throws RemoteException; public void systemBackupRestored() throws RemoteException; + public void notifyCleartextNetwork(int uid, byte[] firstPacket) throws RemoteException; /* * Private non-Binder interfaces @@ -793,4 +795,7 @@ public interface IActivityManager extends IInterface { int CHECK_PERMISSION_WITH_TOKEN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+241; int REGISTER_TASK_STACK_LISTENER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+242; int SYSTEM_BACKUP_RESTORED = IBinder.FIRST_CALL_TRANSACTION+243; + + // Start of M transactions + int NOTIFY_CLEARTEXT_NETWORK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+280; } diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java index 42acbc6..8bf8cd7 100644 --- a/core/java/android/app/IApplicationThread.java +++ b/core/java/android/app/IApplicationThread.java @@ -147,6 +147,7 @@ public interface IApplicationThread extends IInterface { void scheduleCancelVisibleBehind(IBinder token) throws RemoteException; void scheduleBackgroundVisibleBehindChanged(IBinder token, boolean enabled) throws RemoteException; void scheduleEnterAnimationComplete(IBinder token) throws RemoteException; + void notifyCleartextNetwork(byte[] firstPacket) throws RemoteException; String descriptor = "android.app.IApplicationThread"; @@ -204,4 +205,5 @@ public interface IApplicationThread extends IInterface { int CANCEL_VISIBLE_BEHIND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+52; int BACKGROUND_VISIBLE_BEHIND_CHANGED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+53; int ENTER_ANIMATION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+54; + int NOTIFY_CLEARTEXT_NETWORK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+55; } diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java index ece2a33..b01f87e 100644 --- a/core/java/android/app/LoadedApk.java +++ b/core/java/android/app/LoadedApk.java @@ -801,7 +801,7 @@ public final class LoadedApk { if (extras != null) { extras.setAllowFds(false); } - mgr.finishReceiver(this, resultCode, data, extras, false); + mgr.finishReceiver(this, resultCode, data, extras, false, intent.getFlags()); } catch (RemoteException e) { Slog.w(ActivityThread.TAG, "Couldn't finish broadcast to unregistered receiver"); } @@ -826,8 +826,8 @@ public final class LoadedApk { public Args(Intent intent, int resultCode, String resultData, Bundle resultExtras, boolean ordered, boolean sticky, int sendingUser) { super(resultCode, resultData, resultExtras, - mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED, - ordered, sticky, mIIntentReceiver.asBinder(), sendingUser); + mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED, ordered, + sticky, mIIntentReceiver.asBinder(), sendingUser, intent.getFlags()); mCurIntent = intent; mOrdered = ordered; } diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 80b57b7..860b9cc 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -1736,6 +1736,7 @@ public class Notification implements Parcelable builder.setSound(this.sound, this.audioStreamType); builder.setDefaults(this.defaults); builder.setVibrate(this.vibrate); + builder.setDeleteIntent(this.deleteIntent); // now apply the latestEventInfo fields if (contentTitle != null) { diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java index a40b29a..d7c4467 100644 --- a/core/java/android/app/SearchManager.java +++ b/core/java/android/app/SearchManager.java @@ -540,11 +540,6 @@ public class SearchManager private final Context mContext; - /** - * The package associated with this seach manager. - */ - private String mAssociatedPackage; - // package private since they are used by the inner class SearchManagerCallback /* package */ final Handler mHandler; /* package */ OnDismissListener mDismissListener = null; @@ -742,10 +737,6 @@ public class SearchManager public void triggerSearch(String query, ComponentName launchActivity, Bundle appSearchData) { - if (!mAssociatedPackage.equals(launchActivity.getPackageName())) { - throw new IllegalArgumentException("invoking app search on a different package " + - "not associated with this search manager"); - } if (query == null || TextUtils.getTrimmedLength(query) == 0) { Log.w(TAG, "triggerSearch called with empty query, ignoring."); return; diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index 8bfe6d3..90d84ee 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -994,6 +994,47 @@ public class WallpaperManager { } /** + * Clear the wallpaper. + * + * @hide + */ + @SystemApi + public void clearWallpaper() { + if (sGlobals.mService == null) { + Log.w(TAG, "WallpaperService not running"); + return; + } + try { + sGlobals.mService.clearWallpaper(); + } catch (RemoteException e) { + // Ignore + } + } + + /** + * Set the live wallpaper. + * + * This can only be called by packages with android.permission.SET_WALLPAPER_COMPONENT + * permission. + * + * @hide + */ + @SystemApi + public boolean setWallpaperComponent(ComponentName name) { + if (sGlobals.mService == null) { + Log.w(TAG, "WallpaperService not running"); + return false; + } + try { + sGlobals.mService.setWallpaperComponent(name); + return true; + } catch (RemoteException e) { + // Ignore + } + return false; + } + + /** * Set the position of the current wallpaper within any larger space, when * that wallpaper is visible behind the given window. The X and Y offsets * are floating point numbers ranging from 0 to 1, representing where the diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java index 87d785a..1b1e600 100644 --- a/core/java/android/app/backup/BackupAgent.java +++ b/core/java/android/app/backup/BackupAgent.java @@ -105,7 +105,7 @@ import java.util.concurrent.CountDownLatch; */ public abstract class BackupAgent extends ContextWrapper { private static final String TAG = "BackupAgent"; - private static final boolean DEBUG = true; + private static final boolean DEBUG = false; /** @hide */ public static final int TYPE_EOF = 0; diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java index 5175490..0450150 100644 --- a/core/java/android/bluetooth/BluetoothA2dp.java +++ b/core/java/android/bluetooth/BluetoothA2dp.java @@ -199,7 +199,8 @@ public final class BluetoothA2dp implements BluetoothProfile { } public void finalize() { - close(); + // The empty finalize needs to be kept or the + // cts signature tests would fail. } /** * Initiate connection to a profile of the remote bluetooth device. diff --git a/core/java/android/content/BroadcastReceiver.java b/core/java/android/content/BroadcastReceiver.java index 9a32fdf..af74e73 100644 --- a/core/java/android/content/BroadcastReceiver.java +++ b/core/java/android/content/BroadcastReceiver.java @@ -238,6 +238,7 @@ public abstract class BroadcastReceiver { final boolean mInitialStickyHint; final IBinder mToken; final int mSendingUser; + final int mFlags; int mResultCode; String mResultData; @@ -246,8 +247,8 @@ public abstract class BroadcastReceiver { boolean mFinished; /** @hide */ - public PendingResult(int resultCode, String resultData, Bundle resultExtras, - int type, boolean ordered, boolean sticky, IBinder token, int userId) { + public PendingResult(int resultCode, String resultData, Bundle resultExtras, int type, + boolean ordered, boolean sticky, IBinder token, int userId, int flags) { mResultCode = resultCode; mResultData = resultData; mResultExtras = resultExtras; @@ -256,6 +257,7 @@ public abstract class BroadcastReceiver { mInitialStickyHint = sticky; mToken = token; mSendingUser = userId; + mFlags = flags; } /** @@ -417,11 +419,11 @@ public abstract class BroadcastReceiver { } if (mOrderedHint) { am.finishReceiver(mToken, mResultCode, mResultData, mResultExtras, - mAbortBroadcast); + mAbortBroadcast, mFlags); } else { // This broadcast was sent to a component; it is not ordered, // but we still need to tell the activity manager we are done. - am.finishReceiver(mToken, 0, null, null, false); + am.finishReceiver(mToken, 0, null, null, false, mFlags); } } catch (RemoteException ex) { } diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java index ecae52c..a176593 100644 --- a/core/java/android/content/res/AssetManager.java +++ b/core/java/android/content/res/AssetManager.java @@ -627,7 +627,21 @@ public final class AssetManager implements AutoCloseable { * * {@hide} */ - public native final int addOverlayPath(String idmapPath); + + public final int addOverlayPath(String idmapPath) { + synchronized (this) { + int res = addOverlayPathNative(idmapPath); + makeStringBlocks(mStringBlocks); + return res; + } + } + + /** + * See addOverlayPath. + * + * {@hide} + */ + public native final int addOverlayPathNative(String idmapPath); /** * Add multiple sets of assets to the asset manager at once. See diff --git a/core/java/android/content/res/StringBlock.java b/core/java/android/content/res/StringBlock.java index 77b8a33..9652db7 100644 --- a/core/java/android/content/res/StringBlock.java +++ b/core/java/android/content/res/StringBlock.java @@ -311,13 +311,13 @@ final class StringBlock { * the color black is returned instead. * * @param color The color as a string. Can be a resource reference, - * HTML hexadecimal, octal or a name + * hexadecimal, octal or a name * @param foreground True if the color will be used as the foreground color, * false otherwise * * @return A CharacterStyle * - * @see Color#getHtmlColor(String) + * @see Color#parseColor(String) */ private static CharacterStyle getColor(String color, boolean foreground) { int c = 0xff000000; @@ -336,7 +336,11 @@ final class StringBlock { } } } else { - c = Color.getHtmlColor(color); + try { + c = Color.parseColor(color); + } catch (IllegalArgumentException e) { + c = Color.BLACK; + } } } diff --git a/core/java/android/gesture/GestureOverlayView.java b/core/java/android/gesture/GestureOverlayView.java index 6e3a00f..e1a2a25 100644 --- a/core/java/android/gesture/GestureOverlayView.java +++ b/core/java/android/gesture/GestureOverlayView.java @@ -640,7 +640,7 @@ public class GestureOverlayView extends FrameLayout { mStrokeBuffer.add(new GesturePoint(x, y, event.getEventTime())); if (mHandleGestureActions && !mIsGesturing) { - mTotalLength += (float) Math.sqrt(dx * dx + dy * dy); + mTotalLength += (float) Math.hypot(dx, dy); if (mTotalLength > mGestureStrokeLengthThreshold) { final OrientedBoundingBox box = diff --git a/core/java/android/gesture/GestureStroke.java b/core/java/android/gesture/GestureStroke.java index 1d0f0fe..4a324f9 100644 --- a/core/java/android/gesture/GestureStroke.java +++ b/core/java/android/gesture/GestureStroke.java @@ -69,8 +69,7 @@ public class GestureStroke { bx.bottom = p.y; len = 0; } else { - len += Math.sqrt(Math.pow(p.x - tmpPoints[(i - 1) * 2], 2) - + Math.pow(p.y - tmpPoints[(i -1 ) * 2 + 1], 2)); + len += Math.hypot(p.x - tmpPoints[(i - 1) * 2], p.y - tmpPoints[(i -1) * 2 + 1]); bx.union(p.x, p.y); } index++; diff --git a/core/java/android/gesture/GestureUtils.java b/core/java/android/gesture/GestureUtils.java index dd221fc..416279e 100644 --- a/core/java/android/gesture/GestureUtils.java +++ b/core/java/android/gesture/GestureUtils.java @@ -293,7 +293,7 @@ public final class GestureUtils { } float deltaX = currentPointX - lstPointX; float deltaY = currentPointY - lstPointY; - float distance = (float) Math.sqrt(deltaX * deltaX + deltaY * deltaY); + float distance = (float) Math.hypot(deltaX, deltaY); if (distanceSoFar + distance >= increment) { float ratio = (increment - distanceSoFar) / distance; float nx = lstPointX + ratio * deltaX; @@ -379,7 +379,7 @@ public final class GestureUtils { for (int i = 0; i < count; i += 2) { float dx = points[i + 2] - points[i]; float dy = points[i + 3] - points[i + 1]; - sum += Math.sqrt(dx * dx + dy * dy); + sum += Math.hypot(dx, dy); } return sum; } @@ -388,13 +388,13 @@ public final class GestureUtils { float totalLen = computeTotalLength(points); float dx = points[2] - points[0]; float dy = points[3] - points[1]; - return (float) Math.sqrt(dx * dx + dy * dy) / totalLen; + return (float) Math.hypot(dx, dy) / totalLen; } static float computeStraightness(float[] points, float totalLen) { float dx = points[2] - points[0]; float dy = points[3] - points[1]; - return (float) Math.sqrt(dx * dx + dy * dy) / totalLen; + return (float) Math.hypot(dx, dy) / totalLen; } /** diff --git a/core/java/android/hardware/GeomagneticField.java b/core/java/android/hardware/GeomagneticField.java index ef05732..eb26ee5 100644 --- a/core/java/android/hardware/GeomagneticField.java +++ b/core/java/android/hardware/GeomagneticField.java @@ -281,7 +281,7 @@ public class GeomagneticField { * @return Horizontal component of the field strength in nonoteslas. */ public float getHorizontalStrength() { - return (float) Math.sqrt(mX * mX + mY * mY); + return (float) Math.hypot(mX, mY); } /** diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java index 482b1f0..bec9489 100644 --- a/core/java/android/hardware/camera2/CameraDevice.java +++ b/core/java/android/hardware/camera2/CameraDevice.java @@ -183,7 +183,7 @@ public abstract class CameraDevice implements AutoCloseable { * Then obtain the Surface with * {@link android.renderscript.Allocation#getSurface}.</li> * - * <li>For access to raw, uncompressed JPEG data in the application: Create an + * <li>For access to RAW, uncompressed YUV, or compressed JPEG data in the application: Create an * {@link android.media.ImageReader} object with one of the supported output formats given by * {@link StreamConfigurationMap#getOutputFormats()}, setting its size to one of the * corresponding supported sizes by passing the chosen output format into diff --git a/core/java/android/net/LocalSocket.java b/core/java/android/net/LocalSocket.java index 31bc20b..a374a86 100644 --- a/core/java/android/net/LocalSocket.java +++ b/core/java/android/net/LocalSocket.java @@ -29,7 +29,7 @@ import java.net.SocketOptions; */ public class LocalSocket implements Closeable { - private LocalSocketImpl impl; + private final LocalSocketImpl impl; private volatile boolean implCreated; private LocalSocketAddress localAddress; private boolean isBound; diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java index 5c12696..dfe2413 100644 --- a/core/java/android/net/Network.java +++ b/core/java/android/net/Network.java @@ -16,7 +16,6 @@ package android.net; -import android.net.NetworkUtils; import android.os.Parcelable; import android.os.Parcel; import android.system.ErrnoException; @@ -34,15 +33,14 @@ import java.net.SocketException; import java.net.UnknownHostException; import java.net.URL; import java.net.URLConnection; -import java.net.URLStreamHandler; -import java.util.concurrent.atomic.AtomicReference; import javax.net.SocketFactory; import com.android.okhttp.ConnectionPool; -import com.android.okhttp.HostResolver; import com.android.okhttp.HttpHandler; import com.android.okhttp.HttpsHandler; import com.android.okhttp.OkHttpClient; +import com.android.okhttp.OkUrlFactory; +import com.android.okhttp.internal.Internal; /** * Identifies a {@code Network}. This is supplied to applications via @@ -63,10 +61,10 @@ public class Network implements Parcelable { // Objects used to perform per-network operations such as getSocketFactory // and openConnection, and a lock to protect access to them. private volatile NetworkBoundSocketFactory mNetworkBoundSocketFactory = null; - // mLock should be used to control write access to mConnectionPool and mHostResolver. + // mLock should be used to control write access to mConnectionPool and mNetwork. // maybeInitHttpClient() must be called prior to reading either variable. private volatile ConnectionPool mConnectionPool = null; - private volatile HostResolver mHostResolver = null; + private volatile com.android.okhttp.internal.Network mNetwork = null; private Object mLock = new Object(); // Default connection pool values. These are evaluated at startup, just @@ -220,10 +218,10 @@ public class Network implements Parcelable { // out) ConnectionPools. private void maybeInitHttpClient() { synchronized (mLock) { - if (mHostResolver == null) { - mHostResolver = new HostResolver() { + if (mNetwork == null) { + mNetwork = new com.android.okhttp.internal.Network() { @Override - public InetAddress[] getAllByName(String host) throws UnknownHostException { + public InetAddress[] resolveInetAddresses(String host) throws UnknownHostException { return Network.this.getAllByName(host); } }; @@ -278,22 +276,25 @@ public class Network implements Parcelable { if (proxy == null) throw new IllegalArgumentException("proxy is null"); maybeInitHttpClient(); String protocol = url.getProtocol(); - OkHttpClient client; - // TODO: HttpHandler creates OkHttpClients that share the default ResponseCache. + OkUrlFactory okUrlFactory; + // TODO: HttpHandler creates OkUrlFactory instances that share the default ResponseCache. // Could this cause unexpected behavior? if (protocol.equals("http")) { - client = HttpHandler.createHttpOkHttpClient(proxy); + okUrlFactory = HttpHandler.createHttpOkUrlFactory(proxy); } else if (protocol.equals("https")) { - client = HttpsHandler.createHttpsOkHttpClient(proxy); + okUrlFactory = HttpsHandler.createHttpsOkUrlFactory(proxy); } else { - // OkHttpClient only supports HTTP and HTTPS and returns a null URLStreamHandler if + // OkHttp only supports HTTP and HTTPS and returns a null URLStreamHandler if // passed another protocol. throw new MalformedURLException("Invalid URL or unrecognized protocol " + protocol); } - return client.setSocketFactory(getSocketFactory()) - .setHostResolver(mHostResolver) - .setConnectionPool(mConnectionPool) - .open(url); + OkHttpClient client = okUrlFactory.client(); + client.setSocketFactory(getSocketFactory()).setConnectionPool(mConnectionPool); + + // Use internal APIs to change the Network. + Internal.instance.setNetwork(client, mNetwork); + + return okUrlFactory.open(url); } /** diff --git a/core/java/android/net/Proxy.java b/core/java/android/net/Proxy.java index 3477b02..17a84a7 100644 --- a/core/java/android/net/Proxy.java +++ b/core/java/android/net/Proxy.java @@ -22,8 +22,6 @@ import android.content.Context; import android.text.TextUtils; import android.util.Log; -import org.apache.http.HttpHost; - import java.net.InetSocketAddress; import java.net.ProxySelector; import java.net.URI; @@ -37,8 +35,6 @@ import java.util.regex.Pattern; */ public final class Proxy { - // Set to true to enable extra debugging. - private static final boolean DEBUG = false; private static final String TAG = "Proxy"; private static final ProxySelector sDefaultProxySelector; @@ -192,31 +188,6 @@ public final class Proxy { } } - /** - * Returns the preferred proxy to be used by clients. This is a wrapper - * around {@link android.net.Proxy#getHost()}. - * - * @param context the context which will be passed to - * {@link android.net.Proxy#getHost()} - * @param url the target URL for the request - * @note Calling this method requires permission - * android.permission.ACCESS_NETWORK_STATE - * @return The preferred proxy to be used by clients, or null if there - * is no proxy. - * {@hide} - */ - // TODO: Get rid of this method. It's used only in tests. - public static final HttpHost getPreferredHttpHost(Context context, - String url) { - java.net.Proxy prefProxy = getProxy(context, url); - if (prefProxy.equals(java.net.Proxy.NO_PROXY)) { - return null; - } else { - InetSocketAddress sa = (InetSocketAddress)prefProxy.address(); - return new HttpHost(sa.getHostName(), sa.getPort(), "http"); - } - } - private static final boolean isLocalHost(String host) { if (host == null) { return false; diff --git a/core/java/android/net/SSLCertificateSocketFactory.java b/core/java/android/net/SSLCertificateSocketFactory.java index c15e6e5..6654577 100644 --- a/core/java/android/net/SSLCertificateSocketFactory.java +++ b/core/java/android/net/SSLCertificateSocketFactory.java @@ -208,7 +208,7 @@ public class SSLCertificateSocketFactory extends SSLSocketFactory { private SSLSocketFactory makeSocketFactory( KeyManager[] keyManagers, TrustManager[] trustManagers) { try { - OpenSSLContextImpl sslContext = new OpenSSLContextImpl(); + OpenSSLContextImpl sslContext = OpenSSLContextImpl.getPreferred(); sslContext.engineInit(keyManagers, trustManagers, null); sslContext.engineGetClientSessionContext().setPersistentCache(mSessionCache); return sslContext.engineGetSocketFactory(); diff --git a/core/java/android/net/StaticIpConfiguration.java b/core/java/android/net/StaticIpConfiguration.java index 365f2b6..37ee961 100644 --- a/core/java/android/net/StaticIpConfiguration.java +++ b/core/java/android/net/StaticIpConfiguration.java @@ -188,6 +188,7 @@ public class StaticIpConfiguration implements Parcelable { for (InetAddress dnsServer : dnsServers) { NetworkUtils.parcelInetAddress(dest, dnsServer, flags); } + dest.writeString(domains); } protected static void readFromParcel(StaticIpConfiguration s, Parcel in) { @@ -198,5 +199,6 @@ public class StaticIpConfiguration implements Parcelable { for (int i = 0; i < size; i++) { s.dnsServers.add(NetworkUtils.unparcelInetAddress(in)); } + s.domains = in.readString(); } } diff --git a/core/java/android/net/http/CharArrayBuffers.java b/core/java/android/net/http/CharArrayBuffers.java deleted file mode 100644 index 77d45f6..0000000 --- a/core/java/android/net/http/CharArrayBuffers.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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.net.http; - -import org.apache.http.util.CharArrayBuffer; -import org.apache.http.protocol.HTTP; - -/** - * Utility methods for working on CharArrayBuffers. - * - * {@hide} - */ -class CharArrayBuffers { - - static final char uppercaseAddon = 'a' - 'A'; - - /** - * Returns true if the buffer contains the given string. Ignores leading - * whitespace and case. - * - * @param buffer to search - * @param beginIndex index at which we should start - * @param str to search for - */ - static boolean containsIgnoreCaseTrimmed(CharArrayBuffer buffer, - int beginIndex, final String str) { - int len = buffer.length(); - char[] chars = buffer.buffer(); - while (beginIndex < len && HTTP.isWhitespace(chars[beginIndex])) { - beginIndex++; - } - int size = str.length(); - boolean ok = len >= beginIndex + size; - for (int j=0; ok && (j<size); j++) { - char a = chars[beginIndex+j]; - char b = str.charAt(j); - if (a != b) { - a = toLower(a); - b = toLower(b); - ok = a == b; - } - } - return ok; - } - - /** - * Returns index of first occurence ch. Lower cases characters leading up - * to first occurrence of ch. - */ - static int setLowercaseIndexOf(CharArrayBuffer buffer, final int ch) { - - int beginIndex = 0; - int endIndex = buffer.length(); - char[] chars = buffer.buffer(); - - for (int i = beginIndex; i < endIndex; i++) { - char current = chars[i]; - if (current == ch) { - return i; - } else if (current >= 'A' && current <= 'Z'){ - // make lower case - current += uppercaseAddon; - chars[i] = current; - } - } - return -1; - } - - private static char toLower(char c) { - if (c >= 'A' && c <= 'Z'){ - c += uppercaseAddon; - } - return c; - } -} diff --git a/core/java/android/net/http/Connection.java b/core/java/android/net/http/Connection.java index 834ad69..831bd0e 100644 --- a/core/java/android/net/http/Connection.java +++ b/core/java/android/net/http/Connection.java @@ -436,7 +436,7 @@ abstract class Connection { ret = false; String error; if (errorId < 0) { - error = ErrorStrings.getString(errorId, mContext); + error = getEventHandlerErrorString(errorId); } else { Throwable cause = e.getCause(); error = cause != null ? cause.toString() : e.getMessage(); @@ -451,6 +451,61 @@ abstract class Connection { return ret; } + private static String getEventHandlerErrorString(int errorId) { + switch (errorId) { + case EventHandler.OK: + return "OK"; + + case EventHandler.ERROR: + return "ERROR"; + + case EventHandler.ERROR_LOOKUP: + return "ERROR_LOOKUP"; + + case EventHandler.ERROR_UNSUPPORTED_AUTH_SCHEME: + return "ERROR_UNSUPPORTED_AUTH_SCHEME"; + + case EventHandler.ERROR_AUTH: + return "ERROR_AUTH"; + + case EventHandler.ERROR_PROXYAUTH: + return "ERROR_PROXYAUTH"; + + case EventHandler.ERROR_CONNECT: + return "ERROR_CONNECT"; + + case EventHandler.ERROR_IO: + return "ERROR_IO"; + + case EventHandler.ERROR_TIMEOUT: + return "ERROR_TIMEOUT"; + + case EventHandler.ERROR_REDIRECT_LOOP: + return "ERROR_REDIRECT_LOOP"; + + case EventHandler.ERROR_UNSUPPORTED_SCHEME: + return "ERROR_UNSUPPORTED_SCHEME"; + + case EventHandler.ERROR_FAILED_SSL_HANDSHAKE: + return "ERROR_FAILED_SSL_HANDSHAKE"; + + case EventHandler.ERROR_BAD_URL: + return "ERROR_BAD_URL"; + + case EventHandler.FILE_ERROR: + return "FILE_ERROR"; + + case EventHandler.FILE_NOT_FOUND_ERROR: + return "FILE_NOT_FOUND_ERROR"; + + case EventHandler.TOO_MANY_REQUESTS_ERROR: + return "TOO_MANY_REQUESTS_ERROR"; + + default: + return "UNKNOWN_ERROR"; + } + } + HttpContext getHttpContext() { return mHttpContext; } diff --git a/core/java/android/net/http/Headers.java b/core/java/android/net/http/Headers.java index 657e071..0f8b105 100644 --- a/core/java/android/net/http/Headers.java +++ b/core/java/android/net/http/Headers.java @@ -158,7 +158,7 @@ public final class Headers { } public void parseHeader(CharArrayBuffer buffer) { - int pos = CharArrayBuffers.setLowercaseIndexOf(buffer, ':'); + int pos = setLowercaseIndexOf(buffer, ':'); if (pos == -1) { return; } @@ -459,12 +459,63 @@ public final class Headers { } private void setConnectionType(CharArrayBuffer buffer, int pos) { - if (CharArrayBuffers.containsIgnoreCaseTrimmed( - buffer, pos, HTTP.CONN_CLOSE)) { + if (containsIgnoreCaseTrimmed(buffer, pos, HTTP.CONN_CLOSE)) { connectionType = CONN_CLOSE; - } else if (CharArrayBuffers.containsIgnoreCaseTrimmed( + } else if (containsIgnoreCaseTrimmed( buffer, pos, HTTP.CONN_KEEP_ALIVE)) { connectionType = CONN_KEEP_ALIVE; } } + + + /** + * Returns true if the buffer contains the given string. Ignores leading + * whitespace and case. + * + * @param buffer to search + * @param beginIndex index at which we should start + * @param str to search for + */ + static boolean containsIgnoreCaseTrimmed(CharArrayBuffer buffer, + int beginIndex, final String str) { + int len = buffer.length(); + char[] chars = buffer.buffer(); + while (beginIndex < len && HTTP.isWhitespace(chars[beginIndex])) { + beginIndex++; + } + int size = str.length(); + boolean ok = len >= (beginIndex + size); + for (int j=0; ok && (j < size); j++) { + char a = chars[beginIndex + j]; + char b = str.charAt(j); + if (a != b) { + a = Character.toLowerCase(a); + b = Character.toLowerCase(b); + ok = a == b; + } + } + + return true; + } + + /** + * Returns index of first occurence ch. Lower cases characters leading up + * to first occurrence of ch. + */ + static int setLowercaseIndexOf(CharArrayBuffer buffer, final int ch) { + + int beginIndex = 0; + int endIndex = buffer.length(); + char[] chars = buffer.buffer(); + + for (int i = beginIndex; i < endIndex; i++) { + char current = chars[i]; + if (current == ch) { + return i; + } else { + chars[i] = Character.toLowerCase(current); + } + } + return -1; + } } diff --git a/core/java/android/net/http/HttpResponseCache.java b/core/java/android/net/http/HttpResponseCache.java index 2785a15..c6c22e7 100644 --- a/core/java/android/net/http/HttpResponseCache.java +++ b/core/java/android/net/http/HttpResponseCache.java @@ -16,32 +16,33 @@ package android.net.http; -import android.content.Context; +import com.android.okhttp.Cache; +import com.android.okhttp.AndroidShimResponseCache; +import com.android.okhttp.OkCacheContainer; + import java.io.Closeable; import java.io.File; import java.io.IOException; import java.net.CacheRequest; import java.net.CacheResponse; -import java.net.HttpURLConnection; import java.net.ResponseCache; import java.net.URI; import java.net.URLConnection; import java.util.List; import java.util.Map; -import javax.net.ssl.HttpsURLConnection; -import org.apache.http.impl.client.DefaultHttpClient; /** * Caches HTTP and HTTPS responses to the filesystem so they may be reused, - * saving time and bandwidth. This class supports {@link HttpURLConnection} and - * {@link HttpsURLConnection}; there is no platform-provided cache for {@link - * DefaultHttpClient} or {@link AndroidHttpClient}. + * saving time and bandwidth. This class supports {@link + * java.net.HttpURLConnection} and {@link javax.net.ssl.HttpsURLConnection}; + * there is no platform-provided cache for {@link + * org.apache.http.impl.client.DefaultHttpClient} or {@link AndroidHttpClient}. * * <h3>Installing an HTTP response cache</h3> * Enable caching of all of your application's HTTP requests by installing the * cache at application startup. For example, this code installs a 10 MiB cache - * in the {@link Context#getCacheDir() application-specific cache directory} of - * the filesystem}: <pre> {@code + * in the {@link android.content.Context#getCacheDir() application-specific + * cache directory} of the filesystem}: <pre> {@code * protected void onCreate(Bundle savedInstanceState) { * ... * @@ -73,10 +74,10 @@ import org.apache.http.impl.client.DefaultHttpClient; * contain private data.</strong> Although it often has more free space, * external storage is optional and—even if available—can disappear * during use. Retrieve the external cache directory using {@link - * Context#getExternalCacheDir()}. If this method returns null, your application - * should fall back to either not caching or caching on non-external storage. If - * the external storage is removed during use, the cache hit rate will drop to - * zero and ongoing cache reads will fail. + * android.content.Context#getExternalCacheDir()}. If this method returns null, + * your application should fall back to either not caching or caching on + * non-external storage. If the external storage is removed during use, the + * cache hit rate will drop to zero and ongoing cache reads will fail. * * <p>Flushing the cache forces its data to the filesystem. This ensures that * all responses written to the cache will be readable the next time the @@ -147,11 +148,11 @@ import org.apache.http.impl.client.DefaultHttpClient; * } catch (Exception httpResponseCacheNotAvailable) { * }}</pre> */ -public final class HttpResponseCache extends ResponseCache implements Closeable { +public final class HttpResponseCache extends ResponseCache implements Closeable, OkCacheContainer { - private final com.android.okhttp.HttpResponseCache delegate; + private final AndroidShimResponseCache delegate; - private HttpResponseCache(com.android.okhttp.HttpResponseCache delegate) { + private HttpResponseCache(AndroidShimResponseCache delegate) { this.delegate = delegate; } @@ -161,17 +162,14 @@ public final class HttpResponseCache extends ResponseCache implements Closeable */ public static HttpResponseCache getInstalled() { ResponseCache installed = ResponseCache.getDefault(); - if (installed instanceof com.android.okhttp.HttpResponseCache) { - return new HttpResponseCache( - (com.android.okhttp.HttpResponseCache) installed); + if (installed instanceof HttpResponseCache) { + return (HttpResponseCache) installed; } - return null; } /** - * Creates a new HTTP response cache and {@link ResponseCache#setDefault - * sets it} as the system default cache. + * Creates a new HTTP response cache and sets it as the system default cache. * * @param directory the directory to hold cache data. * @param maxSize the maximum size of the cache in bytes. @@ -180,26 +178,26 @@ public final class HttpResponseCache extends ResponseCache implements Closeable * Most applications should respond to this exception by logging a * warning. */ - public static HttpResponseCache install(File directory, long maxSize) throws IOException { + public static synchronized HttpResponseCache install(File directory, long maxSize) + throws IOException { ResponseCache installed = ResponseCache.getDefault(); - if (installed instanceof com.android.okhttp.HttpResponseCache) { - com.android.okhttp.HttpResponseCache installedCache = - (com.android.okhttp.HttpResponseCache) installed; + if (installed instanceof HttpResponseCache) { + HttpResponseCache installedResponseCache = (HttpResponseCache) installed; // don't close and reopen if an equivalent cache is already installed - if (installedCache.getDirectory().equals(directory) - && installedCache.getMaxSize() == maxSize - && !installedCache.isClosed()) { - return new HttpResponseCache(installedCache); + AndroidShimResponseCache trueResponseCache = installedResponseCache.delegate; + if (trueResponseCache.isEquivalent(directory, maxSize)) { + return installedResponseCache; } else { // The HttpResponseCache that owns this object is about to be replaced. - installedCache.close(); + trueResponseCache.close(); } } - com.android.okhttp.HttpResponseCache responseCache = - new com.android.okhttp.HttpResponseCache(directory, maxSize); - ResponseCache.setDefault(responseCache); - return new HttpResponseCache(responseCache); + AndroidShimResponseCache trueResponseCache = + AndroidShimResponseCache.create(directory, maxSize); + HttpResponseCache newResponseCache = new HttpResponseCache(trueResponseCache); + ResponseCache.setDefault(newResponseCache); + return newResponseCache; } @Override public CacheResponse get(URI uri, String requestMethod, @@ -214,10 +212,15 @@ public final class HttpResponseCache extends ResponseCache implements Closeable /** * Returns the number of bytes currently being used to store the values in * this cache. This may be greater than the {@link #maxSize} if a background - * deletion is pending. + * deletion is pending. {@code -1} is returned if the size cannot be determined. */ public long size() { - return delegate.getSize(); + try { + return delegate.size(); + } catch (IOException e) { + // This can occur if the cache failed to lazily initialize. + return -1; + } } /** @@ -225,7 +228,7 @@ public final class HttpResponseCache extends ResponseCache implements Closeable * its data. */ public long maxSize() { - return delegate.getMaxSize(); + return delegate.maxSize(); } /** @@ -271,7 +274,7 @@ public final class HttpResponseCache extends ResponseCache implements Closeable * will remain on the filesystem. */ @Override public void close() throws IOException { - if (ResponseCache.getDefault() == this.delegate) { + if (ResponseCache.getDefault() == this) { ResponseCache.setDefault(null); } delegate.close(); @@ -281,9 +284,16 @@ public final class HttpResponseCache extends ResponseCache implements Closeable * Uninstalls the cache and deletes all of its stored contents. */ public void delete() throws IOException { - if (ResponseCache.getDefault() == this.delegate) { + if (ResponseCache.getDefault() == this) { ResponseCache.setDefault(null); } delegate.delete(); } + + /** @hide Needed for OkHttp integration. */ + @Override + public Cache getCache() { + return delegate.getCache(); + } + } diff --git a/core/java/android/net/http/HttpsConnection.java b/core/java/android/net/http/HttpsConnection.java index 6bf01e2..a8674de 100644 --- a/core/java/android/net/http/HttpsConnection.java +++ b/core/java/android/net/http/HttpsConnection.java @@ -79,7 +79,7 @@ public class HttpsConnection extends Connection { cache = FileClientSessionCache.usingDirectory(sessionDir); } - OpenSSLContextImpl sslContext = new OpenSSLContextImpl(); + OpenSSLContextImpl sslContext = OpenSSLContextImpl.getPreferred(); // here, trust managers is a single trust-all manager TrustManager[] trustManagers = new TrustManager[] { diff --git a/core/java/android/net/http/Timer.java b/core/java/android/net/http/Timer.java deleted file mode 100644 index cc15a30..0000000 --- a/core/java/android/net/http/Timer.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.http; - -import android.os.SystemClock; - -/** - * {@hide} - * Debugging tool - */ -class Timer { - - private long mStart; - private long mLast; - - public Timer() { - mStart = mLast = SystemClock.uptimeMillis(); - } - - public void mark(String message) { - long now = SystemClock.uptimeMillis(); - if (HttpLog.LOGV) { - HttpLog.v(message + " " + (now - mLast) + " total " + (now - mStart)); - } - mLast = now; - } -} diff --git a/core/java/android/net/http/X509TrustManagerExtensions.java b/core/java/android/net/http/X509TrustManagerExtensions.java index 6a63a0c..bb36c20 100644 --- a/core/java/android/net/http/X509TrustManagerExtensions.java +++ b/core/java/android/net/http/X509TrustManagerExtensions.java @@ -36,7 +36,7 @@ import javax.net.ssl.X509TrustManager; */ public class X509TrustManagerExtensions { - TrustManagerImpl mDelegate; + final TrustManagerImpl mDelegate; /** * Constructs a new X509TrustManagerExtensions wrapper. @@ -48,6 +48,7 @@ public class X509TrustManagerExtensions { if (tm instanceof TrustManagerImpl) { mDelegate = (TrustManagerImpl) tm; } else { + mDelegate = null; throw new IllegalArgumentException("tm is an instance of " + tm.getClass().getName() + " which is not a supported type of X509TrustManager"); } diff --git a/core/java/android/nfc/tech/Ndef.java b/core/java/android/nfc/tech/Ndef.java index 5852ce4..fdccaae 100644 --- a/core/java/android/nfc/tech/Ndef.java +++ b/core/java/android/nfc/tech/Ndef.java @@ -51,7 +51,7 @@ import java.io.IOException; * {@link Ndef} on NFC Forum Tag Types 1-4, and implement all NDEF operations * as defined in this class. * - * <p>Some vendors have there own well defined specifications for storing NDEF data + * <p>Some vendors have their own well defined specifications for storing NDEF data * on tags that do not fall into the above categories. Android devices with NFC * should enumerate and implement {@link Ndef} under these vendor specifications * where possible, but it is not mandatory. {@link #getType} returns a String diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java index 4b0cef6..b209690 100644 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -518,7 +518,8 @@ public class Build { * <p>Applications targeting this or a later release will get these * new changes in behavior:</p> * <ul> - * <li> The default result of {android.preference.PreferenceActivity#isValidFragment + * <li> The default result of + * {@link android.preference.PreferenceActivity#isValidFragment(String) * PreferenceActivity.isValueFragment} becomes false instead of true.</li> * <li> In {@link android.webkit.WebView}, apps targeting earlier versions will have * JS URLs evaluated directly and any result of the evaluation will not replace diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java index b8178b4..2d92c7b 100644 --- a/core/java/android/os/Debug.java +++ b/core/java/android/os/Debug.java @@ -104,7 +104,7 @@ public final class Debug /** * This class is used to retrieved various statistics about the memory mappings for this - * process. The returns info broken down by dalvik, native, and other. All results are in kB. + * process. The returned info is broken down by dalvik, native, and other. All results are in kB. */ public static class MemoryInfo implements Parcelable { /** The proportional set size for dalvik heap. (Doesn't include other Dalvik overhead.) */ diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl index 5d5d2b3..f0660eb 100644 --- a/core/java/android/os/INetworkManagementService.aidl +++ b/core/java/android/os/INetworkManagementService.aidl @@ -289,6 +289,8 @@ interface INetworkManagementService */ void setUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces); + void setUidCleartextNetworkPolicy(int uid, int policy); + /** * Return status of bandwidth control module. */ diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index 8307d9b..d52dd30 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -835,6 +835,21 @@ public final class PowerManager { } /** + * Turn off the device. + * + * @param confirm If true, shows a shutdown confirmation dialog. + * @param wait If true, this call waits for the shutdown to complete and does not return. + * + * @hide + */ + public void shutdown(boolean confirm, boolean wait) { + try { + mService.shutdown(confirm, wait); + } catch (RemoteException e) { + } + } + + /** * Intent that is broadcast when the state of {@link #isPowerSaveMode()} changes. * This broadcast is only sent to registered receivers. */ diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index 21a9904..4834f97 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -614,9 +614,9 @@ public class Process { synchronized(Process.class) { ArrayList<String> argsForZygote = new ArrayList<String>(); - // --runtime-init, --setuid=, --setgid=, + // --runtime-args, --setuid=, --setgid=, // and --setgroups= must go first - argsForZygote.add("--runtime-init"); + argsForZygote.add("--runtime-args"); argsForZygote.add("--setuid=" + uid); argsForZygote.add("--setgid=" + gid); if ((debugFlags & Zygote.DEBUG_ENABLE_JNI_LOGGING) != 0) { diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java index 6db5f67..5018711 100644 --- a/core/java/android/os/StrictMode.java +++ b/core/java/android/os/StrictMode.java @@ -32,14 +32,17 @@ import android.util.Slog; import android.view.IWindowManager; import com.android.internal.os.RuntimeInit; - import com.android.internal.util.FastPrintWriter; +import com.android.internal.util.HexDump; + import dalvik.system.BlockGuard; import dalvik.system.CloseGuard; import dalvik.system.VMDebug; import java.io.PrintWriter; import java.io.StringWriter; +import java.net.InetAddress; +import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -137,6 +140,13 @@ public final class StrictMode { */ public static final String VISUAL_PROPERTY = "persist.sys.strictmode.visual"; + /** + * Temporary property used to include {@link #DETECT_VM_CLEARTEXT_NETWORK} + * in {@link VmPolicy.Builder#detectAll()}. Apps can still always opt-into + * detection using {@link VmPolicy.Builder#detectCleartextNetwork()}. + */ + private static final String CLEARTEXT_PROPERTY = "persist.sys.strictmode.nonssl"; + // Only log a duplicate stack trace to the logs every second. private static final long MIN_LOG_INTERVAL_MS = 1000; @@ -150,7 +160,7 @@ public final class StrictMode { // of the Looper. private static final int MAX_OFFENSES_PER_LOOP = 10; - // Thread-policy: + // Byte 1: Thread-policy /** * @hide @@ -177,83 +187,91 @@ public final class StrictMode { private static final int ALL_THREAD_DETECT_BITS = DETECT_DISK_WRITE | DETECT_DISK_READ | DETECT_NETWORK | DETECT_CUSTOM; - // Process-policy: + // Byte 2: Process-policy /** * Note, a "VM_" bit, not thread. * @hide */ - public static final int DETECT_VM_CURSOR_LEAKS = 0x200; // for VmPolicy + public static final int DETECT_VM_CURSOR_LEAKS = 0x01 << 8; // for VmPolicy /** * Note, a "VM_" bit, not thread. * @hide */ - public static final int DETECT_VM_CLOSABLE_LEAKS = 0x400; // for VmPolicy + public static final int DETECT_VM_CLOSABLE_LEAKS = 0x02 << 8; // for VmPolicy /** * Note, a "VM_" bit, not thread. * @hide */ - public static final int DETECT_VM_ACTIVITY_LEAKS = 0x800; // for VmPolicy + public static final int DETECT_VM_ACTIVITY_LEAKS = 0x04 << 8; // for VmPolicy + + /** + * @hide + */ + private static final int DETECT_VM_INSTANCE_LEAKS = 0x08 << 8; // for VmPolicy /** * @hide */ - private static final int DETECT_VM_INSTANCE_LEAKS = 0x1000; // for VmPolicy + public static final int DETECT_VM_REGISTRATION_LEAKS = 0x10 << 8; // for VmPolicy /** * @hide */ - public static final int DETECT_VM_REGISTRATION_LEAKS = 0x2000; // for VmPolicy + private static final int DETECT_VM_FILE_URI_EXPOSURE = 0x20 << 8; // for VmPolicy /** * @hide */ - private static final int DETECT_VM_FILE_URI_EXPOSURE = 0x4000; // for VmPolicy + private static final int DETECT_VM_CLEARTEXT_NETWORK = 0x40 << 8; // for VmPolicy private static final int ALL_VM_DETECT_BITS = DETECT_VM_CURSOR_LEAKS | DETECT_VM_CLOSABLE_LEAKS | DETECT_VM_ACTIVITY_LEAKS | DETECT_VM_INSTANCE_LEAKS | - DETECT_VM_REGISTRATION_LEAKS | DETECT_VM_FILE_URI_EXPOSURE; + DETECT_VM_REGISTRATION_LEAKS | DETECT_VM_FILE_URI_EXPOSURE | + DETECT_VM_CLEARTEXT_NETWORK; + + // Byte 3: Penalty /** * @hide */ - public static final int PENALTY_LOG = 0x10; // normal android.util.Log + public static final int PENALTY_LOG = 0x01 << 16; // normal android.util.Log // Used for both process and thread policy: /** * @hide */ - public static final int PENALTY_DIALOG = 0x20; + public static final int PENALTY_DIALOG = 0x02 << 16; /** * Death on any detected violation. * * @hide */ - public static final int PENALTY_DEATH = 0x40; + public static final int PENALTY_DEATH = 0x04 << 16; /** * Death just for detected network usage. * * @hide */ - public static final int PENALTY_DEATH_ON_NETWORK = 0x200; + public static final int PENALTY_DEATH_ON_NETWORK = 0x08 << 16; /** * Flash the screen during violations. * * @hide */ - public static final int PENALTY_FLASH = 0x800; + public static final int PENALTY_FLASH = 0x10 << 16; /** * @hide */ - public static final int PENALTY_DROPBOX = 0x80; + public static final int PENALTY_DROPBOX = 0x20 << 16; /** * Non-public penalty mode which overrides all the other penalty @@ -266,7 +284,14 @@ public final class StrictMode { * * @hide */ - public static final int PENALTY_GATHER = 0x100; + public static final int PENALTY_GATHER = 0x40 << 16; + + /** + * Death when cleartext network traffic is detected. + * + * @hide + */ + public static final int PENALTY_DEATH_ON_CLEARTEXT_NETWORK = 0x80 << 16; /** * Mask of all the penalty bits valid for thread policies. @@ -275,13 +300,18 @@ public final class StrictMode { PENALTY_LOG | PENALTY_DIALOG | PENALTY_DEATH | PENALTY_DROPBOX | PENALTY_GATHER | PENALTY_DEATH_ON_NETWORK | PENALTY_FLASH; - /** * Mask of all the penalty bits valid for VM policies. */ - private static final int VM_PENALTY_MASK = - PENALTY_LOG | PENALTY_DEATH | PENALTY_DROPBOX; + private static final int VM_PENALTY_MASK = PENALTY_LOG | PENALTY_DEATH | PENALTY_DROPBOX + | PENALTY_DEATH_ON_CLEARTEXT_NETWORK; + /** {@hide} */ + public static final int NETWORK_POLICY_ACCEPT = 0; + /** {@hide} */ + public static final int NETWORK_POLICY_LOG = 1; + /** {@hide} */ + public static final int NETWORK_POLICY_REJECT = 2; // TODO: wrap in some ImmutableHashMap thing. // Note: must be before static initialization of sVmPolicy. @@ -636,9 +666,17 @@ public final class StrictMode { * but will likely expand in future releases. */ public Builder detectAll() { - return enable(DETECT_VM_ACTIVITY_LEAKS | DETECT_VM_CURSOR_LEAKS + int flags = DETECT_VM_ACTIVITY_LEAKS | DETECT_VM_CURSOR_LEAKS | DETECT_VM_CLOSABLE_LEAKS | DETECT_VM_REGISTRATION_LEAKS - | DETECT_VM_FILE_URI_EXPOSURE); + | DETECT_VM_FILE_URI_EXPOSURE; + + // TODO: always add DETECT_VM_CLEARTEXT_NETWORK once we have facility + // for apps to mark sockets that should be ignored + if (SystemProperties.getBoolean(CLEARTEXT_PROPERTY, false)) { + flags |= DETECT_VM_CLEARTEXT_NETWORK; + } + + return enable(flags); } /** @@ -686,15 +724,49 @@ public final class StrictMode { } /** - * Crashes the whole process on violation. This penalty runs at - * the end of all enabled penalties so yo you'll still get - * your logging or other violations before the process dies. + * Detect any network traffic from the calling app which is not + * wrapped in SSL/TLS. This can help you detect places that your app + * is inadvertently sending cleartext data across the network. + * <p> + * Using {@link #penaltyDeath()} or + * {@link #penaltyDeathOnCleartextNetwork()} will block further + * traffic on that socket to prevent accidental data leakage, in + * addition to crashing your process. + * <p> + * Using {@link #penaltyDropBox()} will log the raw contents of the + * packet that triggered the violation. + * <p> + * This inspects both IPv4/IPv6 and TCP/UDP network traffic, but it + * may be subject to false positives, such as when STARTTLS + * protocols or HTTP proxies are used. + * + * @hide + */ + public Builder detectCleartextNetwork() { + return enable(DETECT_VM_CLEARTEXT_NETWORK); + } + + /** + * Crashes the whole process on violation. This penalty runs at the + * end of all enabled penalties so you'll still get your logging or + * other violations before the process dies. */ public Builder penaltyDeath() { return enable(PENALTY_DEATH); } /** + * Crashes the whole process when cleartext network traffic is + * detected. + * + * @see #detectCleartextNetwork() + * @hide + */ + public Builder penaltyDeathOnCleartextNetwork() { + return enable(PENALTY_DEATH_ON_CLEARTEXT_NETWORK); + } + + /** * Log detected violations to the system log. */ public Builder penaltyLog() { @@ -1422,7 +1494,7 @@ public final class StrictMode { } private static class AndroidCloseGuardReporter implements CloseGuard.Reporter { - public void report (String message, Throwable allocationSite) { + public void report(String message, Throwable allocationSite) { onVmPolicyViolation(message, allocationSite); } } @@ -1508,6 +1580,27 @@ public final class StrictMode { sIsIdlerRegistered = true; } } + + int networkPolicy = NETWORK_POLICY_ACCEPT; + if ((sVmPolicyMask & DETECT_VM_CLEARTEXT_NETWORK) != 0) { + if ((sVmPolicyMask & PENALTY_DEATH) != 0 + || (sVmPolicyMask & PENALTY_DEATH_ON_CLEARTEXT_NETWORK) != 0) { + networkPolicy = NETWORK_POLICY_REJECT; + } else { + networkPolicy = NETWORK_POLICY_LOG; + } + } + + final INetworkManagementService netd = INetworkManagementService.Stub.asInterface( + ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE)); + if (netd != null) { + try { + netd.setUidCleartextNetworkPolicy(android.os.Process.myUid(), networkPolicy); + } catch (RemoteException ignored) { + } + } else if (networkPolicy != NETWORK_POLICY_ACCEPT) { + Log.w(TAG, "Dropping requested network policy due to missing service!"); + } } } @@ -1570,6 +1663,13 @@ public final class StrictMode { /** * @hide */ + public static boolean vmCleartextNetworkEnabled() { + return (sVmPolicyMask & DETECT_VM_CLEARTEXT_NETWORK) != 0; + } + + /** + * @hide + */ public static void onSqliteObjectLeaked(String message, Throwable originStack) { onVmPolicyViolation(message, originStack); } @@ -1600,7 +1700,39 @@ public final class StrictMode { */ public static void onFileUriExposed(String location) { final String message = "file:// Uri exposed through " + location; - onVmPolicyViolation(message, new Throwable(message)); + onVmPolicyViolation(null, new Throwable(message)); + } + + /** + * @hide + */ + public static void onCleartextNetworkDetected(byte[] firstPacket) { + byte[] rawAddr = null; + if (firstPacket != null) { + if (firstPacket.length >= 20 && (firstPacket[0] & 0xf0) == 0x40) { + // IPv4 + rawAddr = new byte[4]; + System.arraycopy(firstPacket, 16, rawAddr, 0, 4); + } else if (firstPacket.length >= 40 && (firstPacket[0] & 0xf0) == 0x60) { + // IPv6 + rawAddr = new byte[16]; + System.arraycopy(firstPacket, 24, rawAddr, 0, 16); + } + } + + final int uid = android.os.Process.myUid(); + String msg = "Detected cleartext network traffic from UID " + uid; + if (rawAddr != null) { + try { + msg = "Detected cleartext network traffic from UID " + uid + " to " + + InetAddress.getByAddress(rawAddr); + } catch (UnknownHostException ignored) { + } + } + + final boolean forceDeath = (sVmPolicyMask & PENALTY_DEATH_ON_CLEARTEXT_NETWORK) != 0; + onVmPolicyViolation(HexDump.dumpHexString(firstPacket).trim(), new Throwable(msg), + forceDeath); } // Map from VM violation fingerprint to uptime millis. @@ -1610,10 +1742,18 @@ public final class StrictMode { * @hide */ public static void onVmPolicyViolation(String message, Throwable originStack) { + onVmPolicyViolation(message, originStack, false); + } + + /** + * @hide + */ + public static void onVmPolicyViolation(String message, Throwable originStack, + boolean forceDeath) { final boolean penaltyDropbox = (sVmPolicyMask & PENALTY_DROPBOX) != 0; - final boolean penaltyDeath = (sVmPolicyMask & PENALTY_DEATH) != 0; + final boolean penaltyDeath = ((sVmPolicyMask & PENALTY_DEATH) != 0) || forceDeath; final boolean penaltyLog = (sVmPolicyMask & PENALTY_LOG) != 0; - final ViolationInfo info = new ViolationInfo(originStack, sVmPolicyMask); + final ViolationInfo info = new ViolationInfo(message, originStack, sVmPolicyMask); // Erase stuff not relevant for process-wide violations info.numAnimationsRunning = 0; @@ -2057,6 +2197,8 @@ public final class StrictMode { * @hide */ public static class ViolationInfo { + public String message; + /** * Stack and other stuff info. */ @@ -2118,10 +2260,15 @@ public final class StrictMode { policy = 0; } + public ViolationInfo(Throwable tr, int policy) { + this(null, tr, policy); + } + /** * Create an instance of ViolationInfo initialized from an exception. */ - public ViolationInfo(Throwable tr, int policy) { + public ViolationInfo(String message, Throwable tr, int policy) { + this.message = message; crashInfo = new ApplicationErrorReport.CrashInfo(tr); violationUptimeMillis = SystemClock.uptimeMillis(); this.policy = policy; @@ -2184,6 +2331,7 @@ public final class StrictMode { * and the gathering penalty should be removed. */ public ViolationInfo(Parcel in, boolean unsetGatheringBit) { + message = in.readString(); crashInfo = new ApplicationErrorReport.CrashInfo(in); int rawPolicy = in.readInt(); if (unsetGatheringBit) { @@ -2204,6 +2352,7 @@ public final class StrictMode { * Save a ViolationInfo instance to a parcel. */ public void writeToParcel(Parcel dest, int flags) { + dest.writeString(message); crashInfo.writeToParcel(dest, flags); int start = dest.dataPosition(); dest.writeInt(policy); diff --git a/core/java/android/printservice/PrintService.java b/core/java/android/printservice/PrintService.java index c5aee7b..ae95854 100644 --- a/core/java/android/printservice/PrintService.java +++ b/core/java/android/printservice/PrintService.java @@ -386,7 +386,7 @@ public abstract class PrintService extends Service { @Override public void setClient(IPrintServiceClient client) { - mHandler.obtainMessage(ServiceHandler.MSG_SET_CLEINT, client) + mHandler.obtainMessage(ServiceHandler.MSG_SET_CLIENT, client) .sendToTarget(); } @@ -414,7 +414,7 @@ public abstract class PrintService extends Service { public static final int MSG_STOP_PRINTER_STATE_TRACKING = 7; public static final int MSG_ON_PRINTJOB_QUEUED = 8; public static final int MSG_ON_REQUEST_CANCEL_PRINTJOB = 9; - public static final int MSG_SET_CLEINT = 10; + public static final int MSG_SET_CLIENT = 10; public ServiceHandler(Looper looper) { super(looper, null, true); @@ -528,9 +528,9 @@ public abstract class PrintService extends Service { onPrintJobQueued(new PrintJob(printJobInfo, mClient)); } break; - case MSG_SET_CLEINT: { + case MSG_SET_CLIENT: { if (DEBUG) { - Log.i(LOG_TAG, "MSG_SET_CLEINT " + Log.i(LOG_TAG, "MSG_SET_CLIENT " + getPackageName()); } mClient = (IPrintServiceClient) message.obj; diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java index 4135e8b..1316471 100644 --- a/core/java/android/provider/DocumentsProvider.java +++ b/core/java/android/provider/DocumentsProvider.java @@ -355,7 +355,7 @@ public abstract class DocumentsProvider extends ContentProvider { } /** - * Return documents that that match the given query under the requested + * Return documents that match the given query under the requested * root. The returned documents should be sorted by relevance in descending * order. How documents are matched against the query string is an * implementation detail left to each provider, but it's suggested that at diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 838686a..3e75460 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -6378,14 +6378,7 @@ public final class Settings { public static final String CALL_AUTO_RETRY = "call_auto_retry"; /** - * The preferred network mode 7 = Global - * 6 = EvDo only - * 5 = CDMA w/o EvDo - * 4 = CDMA / EvDo auto - * 3 = GSM / WCDMA auto - * 2 = WCDMA only - * 1 = GSM only - * 0 = GSM / WCDMA preferred + * See RIL_PreferredNetworkType in ril.h * @hide */ public static final String PREFERRED_NETWORK_MODE = diff --git a/core/java/android/security/IKeystoreService.aidl b/core/java/android/security/IKeystoreService.aidl new file mode 100644 index 0000000..bf51ed1 --- /dev/null +++ b/core/java/android/security/IKeystoreService.aidl @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2015, 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.security; + +import android.security.KeystoreArguments; + +/** + * This must be kept manually in sync with system/security/keystore until AIDL + * can generate both Java and C++ bindings. + * + * @hide + */ +interface IKeystoreService { + int test(); + byte[] get(String name); + int insert(String name, in byte[] item, int uid, int flags); + int del(String name, int uid); + int exist(String name, int uid); + String[] saw(String namePrefix, int uid); + int reset(); + int password(String password); + int lock(); + int unlock(String password); + int zero(); + int generate(String name, int uid, int keyType, int keySize, int flags, + in KeystoreArguments args); + int import_key(String name, in byte[] data, int uid, int flags); + byte[] sign(String name, in byte[] data); + int verify(String name, in byte[] data, in byte[] signature); + byte[] get_pubkey(String name); + int del_key(String name, int uid); + int grant(String name, int granteeUid); + int ungrant(String name, int granteeUid); + long getmtime(String name); + int duplicate(String srcKey, int srcUid, String destKey, int destUid); + int is_hardware_backed(String string); + int clear_uid(long uid); + int reset_uid(int uid); + int sync_uid(int sourceUid, int targetUid); + int password_uid(String password, int uid); +} diff --git a/core/java/android/security/IKeystoreService.java b/core/java/android/security/IKeystoreService.java deleted file mode 100644 index 7e9aba0..0000000 --- a/core/java/android/security/IKeystoreService.java +++ /dev/null @@ -1,662 +0,0 @@ -/* - * Copyright (C) 2012 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.security; - -import android.os.Binder; -import android.os.IBinder; -import android.os.IInterface; -import android.os.Parcel; -import android.os.RemoteException; - -/** - * This must be kept manually in sync with system/security/keystore until AIDL - * can generate both Java and C++ bindings. - * - * @hide - */ -public interface IKeystoreService extends IInterface { - public static abstract class Stub extends Binder implements IKeystoreService { - private static class Proxy implements IKeystoreService { - private final IBinder mRemote; - - Proxy(IBinder remote) { - mRemote = remote; - } - - public IBinder asBinder() { - return mRemote; - } - - public String getInterfaceDescriptor() { - return DESCRIPTOR; - } - - public int test() throws RemoteException { - Parcel _data = Parcel.obtain(); - Parcel _reply = Parcel.obtain(); - int _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - mRemote.transact(Stub.TRANSACTION_test, _data, _reply, 0); - _reply.readException(); - _result = _reply.readInt(); - } finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - - public byte[] get(String name) throws RemoteException { - Parcel _data = Parcel.obtain(); - Parcel _reply = Parcel.obtain(); - byte[] _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeString(name); - mRemote.transact(Stub.TRANSACTION_get, _data, _reply, 0); - _reply.readException(); - _result = _reply.createByteArray(); - } finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - - public int insert(String name, byte[] item, int uid, int flags) throws RemoteException { - Parcel _data = Parcel.obtain(); - Parcel _reply = Parcel.obtain(); - int _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeString(name); - _data.writeByteArray(item); - _data.writeInt(uid); - _data.writeInt(flags); - mRemote.transact(Stub.TRANSACTION_insert, _data, _reply, 0); - _reply.readException(); - _result = _reply.readInt(); - } finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - - public int del(String name, int uid) throws RemoteException { - Parcel _data = Parcel.obtain(); - Parcel _reply = Parcel.obtain(); - int _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeString(name); - _data.writeInt(uid); - mRemote.transact(Stub.TRANSACTION_del, _data, _reply, 0); - _reply.readException(); - _result = _reply.readInt(); - } finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - - public int exist(String name, int uid) throws RemoteException { - Parcel _data = Parcel.obtain(); - Parcel _reply = Parcel.obtain(); - int _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeString(name); - _data.writeInt(uid); - mRemote.transact(Stub.TRANSACTION_exist, _data, _reply, 0); - _reply.readException(); - _result = _reply.readInt(); - } finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - - public String[] saw(String name, int uid) throws RemoteException { - Parcel _data = Parcel.obtain(); - Parcel _reply = Parcel.obtain(); - String[] _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeString(name); - _data.writeInt(uid); - mRemote.transact(Stub.TRANSACTION_saw, _data, _reply, 0); - _reply.readException(); - int size = _reply.readInt(); - _result = new String[size]; - for (int i = 0; i < size; i++) { - _result[i] = _reply.readString(); - } - int _ret = _reply.readInt(); - if (_ret != 1) { - return null; - } - } finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - - @Override - public int reset() throws RemoteException { - Parcel _data = Parcel.obtain(); - Parcel _reply = Parcel.obtain(); - int _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - mRemote.transact(Stub.TRANSACTION_reset, _data, _reply, 0); - _reply.readException(); - _result = _reply.readInt(); - } finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - - public int password(String password) throws RemoteException { - Parcel _data = Parcel.obtain(); - Parcel _reply = Parcel.obtain(); - int _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeString(password); - mRemote.transact(Stub.TRANSACTION_password, _data, _reply, 0); - _reply.readException(); - _result = _reply.readInt(); - } finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - - public int lock() throws RemoteException { - Parcel _data = Parcel.obtain(); - Parcel _reply = Parcel.obtain(); - int _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - mRemote.transact(Stub.TRANSACTION_lock, _data, _reply, 0); - _reply.readException(); - _result = _reply.readInt(); - } finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - - public int unlock(String password) throws RemoteException { - Parcel _data = Parcel.obtain(); - Parcel _reply = Parcel.obtain(); - int _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeString(password); - mRemote.transact(Stub.TRANSACTION_unlock, _data, _reply, 0); - _reply.readException(); - _result = _reply.readInt(); - } finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - - @Override - public int zero() throws RemoteException { - Parcel _data = Parcel.obtain(); - Parcel _reply = Parcel.obtain(); - int _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - mRemote.transact(Stub.TRANSACTION_zero, _data, _reply, 0); - _reply.readException(); - _result = _reply.readInt(); - } finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - - public int generate(String name, int uid, int keyType, int keySize, int flags, - byte[][] args) throws RemoteException { - Parcel _data = Parcel.obtain(); - Parcel _reply = Parcel.obtain(); - int _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeString(name); - _data.writeInt(uid); - _data.writeInt(keyType); - _data.writeInt(keySize); - _data.writeInt(flags); - if (args == null) { - _data.writeInt(0); - } else { - _data.writeInt(args.length); - for (int i = 0; i < args.length; i++) { - _data.writeByteArray(args[i]); - } - } - mRemote.transact(Stub.TRANSACTION_generate, _data, _reply, 0); - _reply.readException(); - _result = _reply.readInt(); - } finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - - public int import_key(String name, byte[] data, int uid, int flags) - throws RemoteException { - Parcel _data = Parcel.obtain(); - Parcel _reply = Parcel.obtain(); - int _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeString(name); - _data.writeByteArray(data); - _data.writeInt(uid); - _data.writeInt(flags); - mRemote.transact(Stub.TRANSACTION_import, _data, _reply, 0); - _reply.readException(); - _result = _reply.readInt(); - } finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - - public byte[] sign(String name, byte[] data) throws RemoteException { - Parcel _data = Parcel.obtain(); - Parcel _reply = Parcel.obtain(); - byte[] _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeString(name); - _data.writeByteArray(data); - mRemote.transact(Stub.TRANSACTION_sign, _data, _reply, 0); - _reply.readException(); - _result = _reply.createByteArray(); - } finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - - public int verify(String name, byte[] data, byte[] signature) throws RemoteException { - Parcel _data = Parcel.obtain(); - Parcel _reply = Parcel.obtain(); - int _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeString(name); - _data.writeByteArray(data); - _data.writeByteArray(signature); - mRemote.transact(Stub.TRANSACTION_verify, _data, _reply, 0); - _reply.readException(); - _result = _reply.readInt(); - } finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - - public byte[] get_pubkey(String name) throws RemoteException { - Parcel _data = Parcel.obtain(); - Parcel _reply = Parcel.obtain(); - byte[] _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeString(name); - mRemote.transact(Stub.TRANSACTION_get_pubkey, _data, _reply, 0); - _reply.readException(); - _result = _reply.createByteArray(); - } finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - - public int del_key(String name, int uid) throws RemoteException { - Parcel _data = Parcel.obtain(); - Parcel _reply = Parcel.obtain(); - int _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeString(name); - _data.writeInt(uid); - mRemote.transact(Stub.TRANSACTION_del_key, _data, _reply, 0); - _reply.readException(); - _result = _reply.readInt(); - } finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - - public int grant(String name, int granteeUid) throws RemoteException { - Parcel _data = Parcel.obtain(); - Parcel _reply = Parcel.obtain(); - int _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeString(name); - _data.writeInt(granteeUid); - mRemote.transact(Stub.TRANSACTION_grant, _data, _reply, 0); - _reply.readException(); - _result = _reply.readInt(); - } finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - - public int ungrant(String name, int granteeUid) throws RemoteException { - Parcel _data = Parcel.obtain(); - Parcel _reply = Parcel.obtain(); - int _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeString(name); - _data.writeInt(granteeUid); - mRemote.transact(Stub.TRANSACTION_ungrant, _data, _reply, 0); - _reply.readException(); - _result = _reply.readInt(); - } finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - - @Override - public long getmtime(String name) throws RemoteException { - Parcel _data = Parcel.obtain(); - Parcel _reply = Parcel.obtain(); - long _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeString(name); - mRemote.transact(Stub.TRANSACTION_getmtime, _data, _reply, 0); - _reply.readException(); - _result = _reply.readLong(); - } finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - - @Override - public int duplicate(String srcKey, int srcUid, String destKey, int destUid) - throws RemoteException { - Parcel _data = Parcel.obtain(); - Parcel _reply = Parcel.obtain(); - int _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeString(srcKey); - _data.writeInt(srcUid); - _data.writeString(destKey); - _data.writeInt(destUid); - mRemote.transact(Stub.TRANSACTION_duplicate, _data, _reply, 0); - _reply.readException(); - _result = _reply.readInt(); - } finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - - @Override - public int is_hardware_backed(String keyType) throws RemoteException { - Parcel _data = Parcel.obtain(); - Parcel _reply = Parcel.obtain(); - int _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeString(keyType); - mRemote.transact(Stub.TRANSACTION_is_hardware_backed, _data, _reply, 0); - _reply.readException(); - _result = _reply.readInt(); - } finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - - @Override - public int clear_uid(long uid) throws RemoteException { - Parcel _data = Parcel.obtain(); - Parcel _reply = Parcel.obtain(); - int _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeLong(uid); - mRemote.transact(Stub.TRANSACTION_clear_uid, _data, _reply, 0); - _reply.readException(); - _result = _reply.readInt(); - } finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - - public int reset_uid(int uid) throws RemoteException { - Parcel _data = Parcel.obtain(); - Parcel _reply = Parcel.obtain(); - int _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeInt(uid); - mRemote.transact(Stub.TRANSACTION_reset_uid, _data, _reply, 0); - _reply.readException(); - _result = _reply.readInt(); - } finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - - public int sync_uid(int srcUid, int dstUid) throws RemoteException { - Parcel _data = Parcel.obtain(); - Parcel _reply = Parcel.obtain(); - int _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeInt(srcUid); - _data.writeInt(dstUid); - mRemote.transact(Stub.TRANSACTION_sync_uid, _data, _reply, 0); - _reply.readException(); - _result = _reply.readInt(); - } finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - - public int password_uid(String password, int uid) throws RemoteException { - Parcel _data = Parcel.obtain(); - Parcel _reply = Parcel.obtain(); - int _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeString(password); - _data.writeInt(uid); - mRemote.transact(Stub.TRANSACTION_password_uid, _data, _reply, 0); - _reply.readException(); - _result = _reply.readInt(); - } finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - } - - private static final String DESCRIPTOR = "android.security.keystore"; - - static final int TRANSACTION_test = IBinder.FIRST_CALL_TRANSACTION + 0; - static final int TRANSACTION_get = IBinder.FIRST_CALL_TRANSACTION + 1; - static final int TRANSACTION_insert = IBinder.FIRST_CALL_TRANSACTION + 2; - static final int TRANSACTION_del = IBinder.FIRST_CALL_TRANSACTION + 3; - static final int TRANSACTION_exist = IBinder.FIRST_CALL_TRANSACTION + 4; - static final int TRANSACTION_saw = IBinder.FIRST_CALL_TRANSACTION + 5; - static final int TRANSACTION_reset = IBinder.FIRST_CALL_TRANSACTION + 6; - static final int TRANSACTION_password = IBinder.FIRST_CALL_TRANSACTION + 7; - static final int TRANSACTION_lock = IBinder.FIRST_CALL_TRANSACTION + 8; - static final int TRANSACTION_unlock = IBinder.FIRST_CALL_TRANSACTION + 9; - static final int TRANSACTION_zero = IBinder.FIRST_CALL_TRANSACTION + 10; - static final int TRANSACTION_generate = IBinder.FIRST_CALL_TRANSACTION + 11; - static final int TRANSACTION_import = IBinder.FIRST_CALL_TRANSACTION + 12; - static final int TRANSACTION_sign = IBinder.FIRST_CALL_TRANSACTION + 13; - static final int TRANSACTION_verify = IBinder.FIRST_CALL_TRANSACTION + 14; - static final int TRANSACTION_get_pubkey = IBinder.FIRST_CALL_TRANSACTION + 15; - static final int TRANSACTION_del_key = IBinder.FIRST_CALL_TRANSACTION + 16; - static final int TRANSACTION_grant = IBinder.FIRST_CALL_TRANSACTION + 17; - static final int TRANSACTION_ungrant = IBinder.FIRST_CALL_TRANSACTION + 18; - static final int TRANSACTION_getmtime = IBinder.FIRST_CALL_TRANSACTION + 19; - static final int TRANSACTION_duplicate = IBinder.FIRST_CALL_TRANSACTION + 20; - static final int TRANSACTION_is_hardware_backed = IBinder.FIRST_CALL_TRANSACTION + 21; - static final int TRANSACTION_clear_uid = IBinder.FIRST_CALL_TRANSACTION + 22; - static final int TRANSACTION_reset_uid = IBinder.FIRST_CALL_TRANSACTION + 23; - static final int TRANSACTION_sync_uid = IBinder.FIRST_CALL_TRANSACTION + 24; - static final int TRANSACTION_password_uid = IBinder.FIRST_CALL_TRANSACTION + 25; - - /** - * Cast an IBinder object into an IKeystoreService interface, generating - * a proxy if needed. - */ - public static IKeystoreService asInterface(IBinder obj) { - if (obj == null) { - return null; - } - IInterface iin = obj.queryLocalInterface(DESCRIPTOR); - if (iin != null && iin instanceof IKeystoreService) { - return (IKeystoreService) iin; - } - return new IKeystoreService.Stub.Proxy(obj); - } - - /** Construct the stub at attach it to the interface. */ - public Stub() { - attachInterface(this, DESCRIPTOR); - } - - public IBinder asBinder() { - return this; - } - - @Override - public boolean onTransact(int code, Parcel data, Parcel reply, int flags) - throws RemoteException { - switch (code) { - case INTERFACE_TRANSACTION: { - reply.writeString(DESCRIPTOR); - return true; - } - case TRANSACTION_test: { - data.enforceInterface(DESCRIPTOR); - int resultCode = test(); - reply.writeNoException(); - reply.writeInt(resultCode); - return true; - } - } - return super.onTransact(code, data, reply, flags); - } - } - - public int test() throws RemoteException; - - public byte[] get(String name) throws RemoteException; - - public int insert(String name, byte[] item, int uid, int flags) throws RemoteException; - - public int del(String name, int uid) throws RemoteException; - - public int exist(String name, int uid) throws RemoteException; - - public String[] saw(String name, int uid) throws RemoteException; - - public int reset() throws RemoteException; - - public int password(String password) throws RemoteException; - - public int lock() throws RemoteException; - - public int unlock(String password) throws RemoteException; - - public int zero() throws RemoteException; - - public int generate(String name, int uid, int keyType, int keySize, int flags, byte[][] args) - throws RemoteException; - - public int import_key(String name, byte[] data, int uid, int flags) throws RemoteException; - - public byte[] sign(String name, byte[] data) throws RemoteException; - - public int verify(String name, byte[] data, byte[] signature) throws RemoteException; - - public byte[] get_pubkey(String name) throws RemoteException; - - public int del_key(String name, int uid) throws RemoteException; - - public int grant(String name, int granteeUid) throws RemoteException; - - public int ungrant(String name, int granteeUid) throws RemoteException; - - public long getmtime(String name) throws RemoteException; - - public int duplicate(String srcKey, int srcUid, String destKey, int destUid) - throws RemoteException; - - public int is_hardware_backed(String string) throws RemoteException; - - public int clear_uid(long uid) throws RemoteException; - - public int reset_uid(int uid) throws RemoteException; - - public int sync_uid(int sourceUid, int targetUid) throws RemoteException; - - public int password_uid(String password, int uid) throws RemoteException; -} diff --git a/core/java/android/security/KeystoreArguments.aidl b/core/java/android/security/KeystoreArguments.aidl new file mode 100644 index 0000000..d636414 --- /dev/null +++ b/core/java/android/security/KeystoreArguments.aidl @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2015, 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.security; + +/* @hide */ +parcelable KeystoreArguments; diff --git a/core/java/android/security/KeystoreArguments.java b/core/java/android/security/KeystoreArguments.java new file mode 100644 index 0000000..16054e5 --- /dev/null +++ b/core/java/android/security/KeystoreArguments.java @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2015, 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.security; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Class for handling the additional arguments to some keystore binder calls. + * This must be kept in sync with the deserialization code in system/security/keystore. + * @hide + */ +public class KeystoreArguments implements Parcelable { + public byte[][] args; + + public static final Parcelable.Creator<KeystoreArguments> CREATOR = new + Parcelable.Creator<KeystoreArguments>() { + public KeystoreArguments createFromParcel(Parcel in) { + return new KeystoreArguments(in); + } + public KeystoreArguments[] newArray(int size) { + return new KeystoreArguments[size]; + } + }; + + public KeystoreArguments() { + args = null; + } + + public KeystoreArguments(byte[][] args) { + this.args = args; + } + + private KeystoreArguments(Parcel in) { + readFromParcel(in); + } + + @Override + public void writeToParcel(Parcel out, int flags) { + if (args == null) { + out.writeInt(0); + } else { + out.writeInt(args.length); + for (byte[] arg : args) { + out.writeByteArray(arg); + } + } + } + + private void readFromParcel(Parcel in) { + int length = in.readInt(); + args = new byte[length][]; + for (int i = 0; i < length; i++) { + args[i] = in.createByteArray(); + } + } + + @Override + public int describeContents() { + return 0; + } +} diff --git a/core/java/android/text/BoringLayout.java b/core/java/android/text/BoringLayout.java index 6f00707..e78cf8f 100644 --- a/core/java/android/text/BoringLayout.java +++ b/core/java/android/text/BoringLayout.java @@ -20,7 +20,6 @@ import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Path; import android.text.style.ParagraphStyle; -import android.util.FloatMath; /** * A BoringLayout is a very simple Layout implementation for text that @@ -207,7 +206,7 @@ public class BoringLayout extends Layout implements TextUtils.EllipsizeCallback TextLine line = TextLine.obtain(); line.set(paint, source, 0, source.length(), Layout.DIR_LEFT_TO_RIGHT, Layout.DIRS_ALL_LEFT_TO_RIGHT, false, null); - mMax = (int) FloatMath.ceil(line.metrics(null)); + mMax = (int) Math.ceil(line.metrics(null)); TextLine.recycle(line); } @@ -301,7 +300,7 @@ public class BoringLayout extends Layout implements TextUtils.EllipsizeCallback TextLine line = TextLine.obtain(); line.set(paint, text, 0, length, Layout.DIR_LEFT_TO_RIGHT, Layout.DIRS_ALL_LEFT_TO_RIGHT, false, null); - fm.width = (int) FloatMath.ceil(line.metrics(fm)); + fm.width = (int) Math.ceil(line.metrics(fm)); TextLine.recycle(line); return fm; diff --git a/core/java/android/text/Html.java b/core/java/android/text/Html.java index 2fcc597..dc93bc2 100644 --- a/core/java/android/text/Html.java +++ b/core/java/android/text/Html.java @@ -61,7 +61,7 @@ public class Html { */ public static interface ImageGetter { /** - * This methos is called when the HTML parser encounters an + * This method is called when the HTML parser encounters an * <img> tag. The <code>source</code> argument is the * string from the "src" attribute; the return value should be * a Drawable representation of the image or <code>null</code> diff --git a/core/java/android/text/format/DateFormat.java b/core/java/android/text/format/DateFormat.java index 72bbb2b..c03f7a6 100755 --- a/core/java/android/text/format/DateFormat.java +++ b/core/java/android/text/format/DateFormat.java @@ -278,73 +278,18 @@ public class DateFormat { */ public static String getTimeFormatString(Context context, int userHandle) { LocaleData d = LocaleData.get(context.getResources().getConfiguration().locale); - return is24HourFormat(context, userHandle) ? d.timeFormat24 : d.timeFormat12; + return is24HourFormat(context, userHandle) ? d.timeFormat_Hm : d.timeFormat_hm; } /** * Returns a {@link java.text.DateFormat} object that can format the date - * in short form (such as 12/31/1999) according - * to the current locale and the user's date-order preference. + * in short form according to the current locale. + * * @param context the application context * @return the {@link java.text.DateFormat} object that properly formats the date. */ public static java.text.DateFormat getDateFormat(Context context) { - String value = Settings.System.getString(context.getContentResolver(), - Settings.System.DATE_FORMAT); - - return getDateFormatForSetting(context, value); - } - - /** - * Returns a {@link java.text.DateFormat} object to format the date - * as if the date format setting were set to <code>value</code>, - * including null to use the locale's default format. - * @param context the application context - * @param value the date format setting string to interpret for - * the current locale - * @hide - */ - public static java.text.DateFormat getDateFormatForSetting(Context context, - String value) { - String format = getDateFormatStringForSetting(context, value); - return new java.text.SimpleDateFormat(format); - } - - private static String getDateFormatStringForSetting(Context context, String value) { - if (value != null) { - int month = value.indexOf('M'); - int day = value.indexOf('d'); - int year = value.indexOf('y'); - - if (month >= 0 && day >= 0 && year >= 0) { - String template = context.getString(R.string.numeric_date_template); - if (year < month && year < day) { - if (month < day) { - value = String.format(template, "yyyy", "MM", "dd"); - } else { - value = String.format(template, "yyyy", "dd", "MM"); - } - } else if (month < day) { - if (day < year) { - value = String.format(template, "MM", "dd", "yyyy"); - } else { // unlikely - value = String.format(template, "MM", "yyyy", "dd"); - } - } else { // day < month - if (month < year) { - value = String.format(template, "dd", "MM", "yyyy"); - } else { // unlikely - value = String.format(template, "dd", "yyyy", "MM"); - } - } - - return value; - } - } - - // The setting is not set; use the locale's default. - LocaleData d = LocaleData.get(context.getResources().getConfiguration().locale); - return d.shortDateFormat4; + return java.text.DateFormat.getDateInstance(java.text.DateFormat.SHORT); } /** @@ -377,14 +322,16 @@ public class DateFormat { * order returned here. */ public static char[] getDateFormatOrder(Context context) { - return ICU.getDateFormatOrder(getDateFormatString(context)); + return ICU.getDateFormatOrder(getDateFormatString()); } - private static String getDateFormatString(Context context) { - String value = Settings.System.getString(context.getContentResolver(), - Settings.System.DATE_FORMAT); + private static String getDateFormatString() { + java.text.DateFormat df = java.text.DateFormat.getDateInstance(java.text.DateFormat.SHORT); + if (df instanceof SimpleDateFormat) { + return ((SimpleDateFormat) df).toPattern(); + } - return getDateFormatStringForSetting(context, value); + throw new AssertionError("!(df instanceof SimpleDateFormat)"); } /** diff --git a/core/java/android/text/format/Time.java b/core/java/android/text/format/Time.java index 1e04eb4..0c66709 100644 --- a/core/java/android/text/format/Time.java +++ b/core/java/android/text/format/Time.java @@ -215,13 +215,15 @@ public class Time { * <p> * If "ignoreDst" is true, then this method sets the "isDst" field to -1 * (the "unknown" value) before normalizing. It then computes the - * correct value for "isDst". + * time in milliseconds and sets the correct value for "isDst" if the + * fields resolve to a valid date / time. * * <p> * See {@link #toMillis(boolean)} for more information about when to - * use <tt>true</tt> or <tt>false</tt> for "ignoreDst". + * use <tt>true</tt> or <tt>false</tt> for "ignoreDst" and when {@code -1} + * might be returned. * - * @return the UTC milliseconds since the epoch + * @return the UTC milliseconds since the epoch, or {@code -1} */ public long normalize(boolean ignoreDst) { calculator.copyFieldsFromTime(this); @@ -317,6 +319,11 @@ public class Time { * a} is less than {@code b}, a positive number if {@code a} is greater than * {@code b}, or 0 if they are equal. * + * <p> + * This method can return an incorrect answer when the date / time fields of + * either {@code Time} have been set to a local time that contradicts the + * available timezone information. + * * @param a first {@code Time} instance to compare * @param b second {@code Time} instance to compare * @throws NullPointerException if either argument is {@code null} @@ -730,6 +737,14 @@ public class Time { * <p> * You should also use <tt>toMillis(false)</tt> if you want * to read back the same milliseconds that you set with {@link #set(long)} + * + * <p> + * This method can return {@code -1} when the date / time fields have been + * set to a local time that conflicts with available timezone information. + * For example, when daylight savings transitions cause an hour to be + * skipped: times within that hour will return {@code -1} if isDst = + * {@code -1}. + * * or {@link #set(Time)} or after parsing a date string. */ public long toMillis(boolean ignoreDst) { @@ -825,6 +840,10 @@ public class Time { * Returns true if the time represented by this Time object occurs before * the given time. * + * <p> + * Equivalent to {@code Time.compare(this, that) < 0}. See + * {@link #compare(Time, Time)} for details. + * * @param that a given Time object to compare against * @return true if this time is less than the given time */ @@ -837,6 +856,10 @@ public class Time { * Returns true if the time represented by this Time object occurs after * the given time. * + * <p> + * Equivalent to {@code Time.compare(this, that) > 0}. See + * {@link #compare(Time, Time)} for details. + * * @param that a given Time object to compare against * @return true if this time is greater than the given time */ @@ -917,6 +940,10 @@ public class Time { * Returns true if the day of the given time is the epoch on the Julian Calendar * (January 1, 1970 on the Gregorian calendar). * + * <p> + * This method can return an incorrect answer when the date / time fields have + * been set to a local time that contradicts the available timezone information. + * * @param time the time to test * @return true if epoch. */ diff --git a/core/java/android/util/FloatMath.java b/core/java/android/util/FloatMath.java index bdcf5ca..8f488af 100644 --- a/core/java/android/util/FloatMath.java +++ b/core/java/android/util/FloatMath.java @@ -17,10 +17,13 @@ package android.util; /** - * Math routines similar to those found in {@link java.lang.Math}. On - * versions of Android with a JIT, these are significantly slower than - * the equivalent {@code Math} functions, which should be used in preference - * to these. + * Math routines similar to those found in {@link java.lang.Math}. + * + * <p>Historically these methods were faster than the equivalent double-based + * {@link java.lang.Math} methods. On versions of Android with a JIT they + * became slower and have since been re-implemented to wrap calls to + * {@link java.lang.Math}. {@link java.lang.Math} should be used in + * preference. * * @deprecated Use {@link java.lang.Math} instead. */ @@ -37,7 +40,9 @@ public class FloatMath { * @param value to be converted * @return the floor of value */ - public static native float floor(float value); + public static float floor(float value) { + return (float) Math.floor(value); + } /** * Returns the float conversion of the most negative (i.e. closest to @@ -46,7 +51,9 @@ public class FloatMath { * @param value to be converted * @return the ceiling of value */ - public static native float ceil(float value); + public static float ceil(float value) { + return (float) Math.ceil(value); + } /** * Returns the closest float approximation of the sine of the argument. @@ -54,7 +61,9 @@ public class FloatMath { * @param angle to compute the cosine of, in radians * @return the sine of angle */ - public static native float sin(float angle); + public static float sin(float angle) { + return (float) Math.sin(angle); + } /** * Returns the closest float approximation of the cosine of the argument. @@ -62,7 +71,9 @@ public class FloatMath { * @param angle to compute the cosine of, in radians * @return the cosine of angle */ - public static native float cos(float angle); + public static float cos(float angle) { + return (float) Math.cos(angle); + } /** * Returns the closest float approximation of the square root of the @@ -71,7 +82,9 @@ public class FloatMath { * @param value to compute sqrt of * @return the square root of value */ - public static native float sqrt(float value); + public static float sqrt(float value) { + return (float) Math.sqrt(value); + } /** * Returns the closest float approximation of the raising "e" to the power @@ -80,7 +93,9 @@ public class FloatMath { * @param value to compute the exponential of * @return the exponential of value */ - public static native float exp(float value); + public static float exp(float value) { + return (float) Math.exp(value); + } /** * Returns the closest float approximation of the result of raising {@code @@ -90,7 +105,9 @@ public class FloatMath { * @param y the exponent of the operation. * @return {@code x} to the power of {@code y}. */ - public static native float pow(float x, float y); + public static float pow(float x, float y) { + return (float) Math.pow(x, y); + } /** * Returns {@code sqrt(}<i>{@code x}</i><sup>{@code 2}</sup>{@code +} <i> @@ -100,5 +117,7 @@ public class FloatMath { * @param y a float number * @return the hypotenuse */ - public static native float hypot(float x, float y); + public static float hypot(float x, float y) { + return (float) Math.hypot(x, y); + } } diff --git a/core/java/android/util/MathUtils.java b/core/java/android/util/MathUtils.java index 13a692e..36d5b50 100644 --- a/core/java/android/util/MathUtils.java +++ b/core/java/android/util/MathUtils.java @@ -94,7 +94,7 @@ public final class MathUtils { public static float dist(float x1, float y1, float x2, float y2) { final float x = (x2 - x1); final float y = (y2 - y1); - return (float) Math.sqrt(x * x + y * y); + return (float) Math.hypot(x, y); } public static float dist(float x1, float y1, float z1, float x2, float y2, float z2) { @@ -105,7 +105,7 @@ public final class MathUtils { } public static float mag(float a, float b) { - return (float) Math.sqrt(a * a + b * b); + return (float) Math.hypot(a, b); } public static float mag(float a, float b, float c) { diff --git a/core/java/android/util/NtpTrustedTime.java b/core/java/android/util/NtpTrustedTime.java index 8ebcacd..ed2d3c6 100644 --- a/core/java/android/util/NtpTrustedTime.java +++ b/core/java/android/util/NtpTrustedTime.java @@ -24,6 +24,7 @@ import android.net.NetworkInfo; import android.net.SntpClient; import android.os.SystemClock; import android.provider.Settings; +import android.text.TextUtils; /** * {@link TrustedTime} that connects with a remote NTP server as its trusted @@ -79,7 +80,7 @@ public class NtpTrustedTime implements TrustedTime { @Override public boolean forceRefresh() { - if (mServer == null) { + if (TextUtils.isEmpty(mServer)) { // missing server, so no trusted time available return false; } diff --git a/core/java/android/view/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java index 42a58a8..6508cca 100644 --- a/core/java/android/view/ScaleGestureDetector.java +++ b/core/java/android/view/ScaleGestureDetector.java @@ -21,7 +21,6 @@ import android.content.res.Resources; import android.os.Build; import android.os.Handler; import android.os.SystemClock; -import android.util.FloatMath; /** * Detects scaling transformation gestures using the supplied {@link MotionEvent}s. @@ -394,7 +393,7 @@ public class ScaleGestureDetector { if (inDoubleTapMode()) { span = spanY; } else { - span = FloatMath.sqrt(spanX * spanX + spanY * spanY); + span = (float) Math.hypot(spanX, spanY); } // Dispatch begin/end events as needed. diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index fd50c4d..719e780 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -6316,8 +6316,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager /** * Information about how wide the view wants to be. Can be one of the - * constants FILL_PARENT (replaced by MATCH_PARENT , - * in API Level 8) or WRAP_CONTENT. or an exact size. + * constants FILL_PARENT (replaced by MATCH_PARENT + * in API Level 8) or WRAP_CONTENT, or an exact size. */ @ViewDebug.ExportedProperty(category = "layout", mapping = { @ViewDebug.IntToString(from = MATCH_PARENT, to = "MATCH_PARENT"), @@ -6327,8 +6327,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager /** * Information about how tall the view wants to be. Can be one of the - * constants FILL_PARENT (replaced by MATCH_PARENT , - * in API Level 8) or WRAP_CONTENT. or an exact size. + * constants FILL_PARENT (replaced by MATCH_PARENT + * in API Level 8) or WRAP_CONTENT, or an exact size. */ @ViewDebug.ExportedProperty(category = "layout", mapping = { @ViewDebug.IntToString(from = MATCH_PARENT, to = "MATCH_PARENT"), diff --git a/core/java/android/net/http/ErrorStrings.java b/core/java/android/webkit/LegacyErrorStrings.java index 8383681..11fc05d 100644 --- a/core/java/android/net/http/ErrorStrings.java +++ b/core/java/android/webkit/LegacyErrorStrings.java @@ -14,9 +14,10 @@ * limitations under the License. */ -package android.net.http; +package android.webkit; import android.content.Context; +import android.net.http.EventHandler; import android.util.Log; /** @@ -24,8 +25,8 @@ import android.util.Log; * * {@hide} */ -public class ErrorStrings { - private ErrorStrings() { /* Utility class, don't instantiate. */ } +class LegacyErrorStrings { + private LegacyErrorStrings() { /* Utility class, don't instantiate. */ } private static final String LOGTAG = "Http"; @@ -33,7 +34,7 @@ public class ErrorStrings { * Get the localized error message resource for the given error code. * If the code is unknown, we'll return a generic error message. */ - public static String getString(int errorCode, Context context) { + static String getString(int errorCode, Context context) { return context.getText(getResource(errorCode)).toString(); } @@ -41,7 +42,7 @@ public class ErrorStrings { * Get the localized error message resource for the given error code. * If the code is unknown, we'll return a generic error message. */ - public static int getResource(int errorCode) { + private static int getResource(int errorCode) { switch(errorCode) { case EventHandler.OK: return com.android.internal.R.string.httpErrorOk; diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 48712bb..bab1f3b 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -2152,7 +2152,7 @@ public class WebView extends AbsoluteLayout /** * In addition to the FindListener that the user may set via the WebView.setFindListener * API, FindActionModeCallback will register it's own FindListener. We keep them separate - * via this class so that that the two FindListeners can potentially exist at once. + * via this class so that the two FindListeners can potentially exist at once. */ private class FindListenerDistributor implements FindListener { private FindListener mFindDialogFindListener; diff --git a/core/java/android/webkit/WebViewDelegate.java b/core/java/android/webkit/WebViewDelegate.java index e03445e..ac360fa 100644 --- a/core/java/android/webkit/WebViewDelegate.java +++ b/core/java/android/webkit/WebViewDelegate.java @@ -22,7 +22,6 @@ import android.app.Application; import android.content.Context; import android.content.res.Resources; import android.graphics.Canvas; -import android.net.http.ErrorStrings; import android.os.SystemProperties; import android.os.Trace; import android.util.SparseArray; @@ -150,7 +149,7 @@ public final class WebViewDelegate { * Returns the error string for the given {@code errorCode}. */ public String getErrorString(Context context, int errorCode) { - return ErrorStrings.getString(errorCode, context); + return LegacyErrorStrings.getString(errorCode, context); } /** diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 523f970..1e269a3 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -2395,7 +2395,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te lp.itemId = mAdapter.getItemId(position); } lp.viewType = mAdapter.getItemViewType(position); - child.setLayoutParams(lp); + if (lp != vlp) { + child.setLayoutParams(lp); + } } class ListItemAccessibilityDelegate extends AccessibilityDelegate { diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java index 4800c7f..a3ce808 100644 --- a/core/java/android/widget/AbsSeekBar.java +++ b/core/java/android/widget/AbsSeekBar.java @@ -695,19 +695,20 @@ public abstract class AbsSeekBar extends ProgressBar { @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (isEnabled()) { - int progress = getProgress(); + int increment = mKeyProgressIncrement; switch (keyCode) { case KeyEvent.KEYCODE_DPAD_LEFT: - if (progress <= 0) break; - setProgress(progress - mKeyProgressIncrement, true); - onKeyChange(); - return true; - + increment = -increment; + // fallthrough case KeyEvent.KEYCODE_DPAD_RIGHT: - if (progress >= getMax()) break; - setProgress(progress + mKeyProgressIncrement, true); - onKeyChange(); - return true; + increment = isLayoutRtl() ? -increment : increment; + int progress = getProgress() + increment; + if (progress > 0 && progress < getMax()) { + setProgress(progress, true); + onKeyChange(); + return true; + } + break; } } diff --git a/core/java/android/widget/DateTimeView.java b/core/java/android/widget/DateTimeView.java index 443884a..db17df7 100644 --- a/core/java/android/widget/DateTimeView.java +++ b/core/java/android/widget/DateTimeView.java @@ -156,7 +156,7 @@ public class DateTimeView extends TextView { format = getTimeFormat(); break; case SHOW_MONTH_DAY_YEAR: - format = getDateFormat(); + format = DateFormat.getDateInstance(DateFormat.SHORT); break; default: throw new RuntimeException("unknown display value: " + display); @@ -196,21 +196,6 @@ public class DateTimeView extends TextView { return android.text.format.DateFormat.getTimeFormat(getContext()); } - private DateFormat getDateFormat() { - String format = Settings.System.getString(getContext().getContentResolver(), - Settings.System.DATE_FORMAT); - if (format == null || "".equals(format)) { - return DateFormat.getDateInstance(DateFormat.SHORT); - } else { - try { - return new SimpleDateFormat(format); - } catch (IllegalArgumentException e) { - // If we tried to use a bad format string, fall back to a default. - return DateFormat.getDateInstance(DateFormat.SHORT); - } - } - } - void clearFormatAndUpdate() { mLastFormat = null; update(); @@ -283,14 +268,10 @@ public class DateTimeView extends TextView { filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); context.registerReceiver(mReceiver, filter); - - final Uri uri = Settings.System.getUriFor(Settings.System.DATE_FORMAT); - context.getContentResolver().registerContentObserver(uri, true, mObserver); } void unregister(Context context) { context.unregisterReceiver(mReceiver); - context.getContentResolver().unregisterContentObserver(mObserver); } } } diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java index 2e9858c..ba6f061 100644 --- a/core/java/android/widget/ListView.java +++ b/core/java/android/widget/ListView.java @@ -2420,10 +2420,15 @@ public class ListView extends AbsListView { (ViewGroup) selectedView, currentFocus, direction); if (nextFocus != null) { // do the math to get interesting rect in next focus' coordinates - currentFocus.getFocusedRect(mTempRect); - offsetDescendantRectToMyCoords(currentFocus, mTempRect); - offsetRectIntoDescendantCoords(nextFocus, mTempRect); - if (nextFocus.requestFocus(direction, mTempRect)) { + Rect focusedRect = mTempRect; + if (currentFocus != null) { + currentFocus.getFocusedRect(focusedRect); + offsetDescendantRectToMyCoords(currentFocus, focusedRect); + offsetRectIntoDescendantCoords(nextFocus, focusedRect); + } else { + focusedRect = null; + } + if (nextFocus.requestFocus(direction, focusedRect)) { return true; } } @@ -2556,8 +2561,10 @@ public class ListView extends AbsListView { if (mItemsCanFocus && (focusResult == null) && selectedView != null && selectedView.hasFocus()) { final View focused = selectedView.findFocus(); - if (!isViewAncestorOf(focused, this) || distanceToView(focused) > 0) { - focused.clearFocus(); + if (focused != null) { + if (!isViewAncestorOf(focused, this) || distanceToView(focused) > 0) { + focused.clearFocus(); + } } } diff --git a/core/java/android/widget/OverScroller.java b/core/java/android/widget/OverScroller.java index a40d4f8..451e493 100644 --- a/core/java/android/widget/OverScroller.java +++ b/core/java/android/widget/OverScroller.java @@ -18,7 +18,6 @@ package android.widget; import android.content.Context; import android.hardware.SensorManager; -import android.util.FloatMath; import android.util.Log; import android.view.ViewConfiguration; import android.view.animation.AnimationUtils; @@ -181,9 +180,7 @@ public class OverScroller { * @return The original velocity less the deceleration, norm of the X and Y velocity vector. */ public float getCurrVelocity() { - float squaredNorm = mScrollerX.mCurrVelocity * mScrollerX.mCurrVelocity; - squaredNorm += mScrollerY.mCurrVelocity * mScrollerY.mCurrVelocity; - return FloatMath.sqrt(squaredNorm); + return (float) Math.hypot(mScrollerX.mCurrVelocity, mScrollerY.mCurrVelocity); } /** diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java index 396c0b9..5419ab6 100644 --- a/core/java/android/widget/PopupWindow.java +++ b/core/java/android/widget/PopupWindow.java @@ -378,10 +378,10 @@ public class PopupWindow { } /** - * Set the flag on popup to ignore cheek press event; by default this flag + * Set the flag on popup to ignore cheek press events; by default this flag * is set to false - * which means the pop wont ignore cheek press dispatch events. - * + * which means the popup will not ignore cheek press dispatch events. + * * <p>If the popup is showing, calling this method will take effect only * the next time the popup is shown or through a manual call to one of * the {@link #update()} methods.</p> diff --git a/core/java/android/widget/Scroller.java b/core/java/android/widget/Scroller.java index 5e88a96..357c9c3 100644 --- a/core/java/android/widget/Scroller.java +++ b/core/java/android/widget/Scroller.java @@ -19,7 +19,6 @@ package android.widget; import android.content.Context; import android.hardware.SensorManager; import android.os.Build; -import android.util.FloatMath; import android.view.ViewConfiguration; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; @@ -425,7 +424,7 @@ public class Scroller { float dx = (float) (mFinalX - mStartX); float dy = (float) (mFinalY - mStartY); - float hyp = FloatMath.sqrt(dx * dx + dy * dy); + float hyp = (float) Math.hypot(dx, dy); float ndx = dx / hyp; float ndy = dy / hyp; @@ -442,7 +441,7 @@ public class Scroller { mMode = FLING_MODE; mFinished = false; - float velocity = FloatMath.sqrt(velocityX * velocityX + velocityY * velocityY); + float velocity = (float) Math.hypot(velocityX, velocityY); mVelocity = velocity; mDuration = getSplineFlingDuration(velocity); diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java index d2e718c..9e168b8 100644 --- a/core/java/android/widget/StackView.java +++ b/core/java/android/widget/StackView.java @@ -1050,10 +1050,8 @@ public class StackView extends AdapterViewAnimator { if (mView != null) { final LayoutParams viewLp = (LayoutParams) mView.getLayoutParams(); - float d = (float) Math.sqrt(Math.pow(viewLp.horizontalOffset, 2) + - Math.pow(viewLp.verticalOffset, 2)); - float maxd = (float) Math.sqrt(Math.pow(mSlideAmount, 2) + - Math.pow(0.4f * mSlideAmount, 2)); + float d = (float) Math.hypot(viewLp.horizontalOffset, viewLp.verticalOffset); + float maxd = (float) Math.hypot(mSlideAmount, 0.4f * mSlideAmount); if (velocity == 0) { return (invert ? (1 - d / maxd) : d / maxd) * DEFAULT_ANIMATION_DURATION; diff --git a/core/java/android/widget/TextClock.java b/core/java/android/widget/TextClock.java index a98d272..e2acaac 100644 --- a/core/java/android/widget/TextClock.java +++ b/core/java/android/widget/TextClock.java @@ -230,10 +230,10 @@ public class TextClock extends TextView { if (mFormat12 == null || mFormat24 == null) { LocaleData ld = LocaleData.get(getContext().getResources().getConfiguration().locale); if (mFormat12 == null) { - mFormat12 = ld.timeFormat12; + mFormat12 = ld.timeFormat_hm; } if (mFormat24 == null) { - mFormat24 = ld.timeFormat24; + mFormat24 = ld.timeFormat_Hm; } } @@ -457,9 +457,9 @@ public class TextClock extends TextView { LocaleData ld = LocaleData.get(getContext().getResources().getConfiguration().locale); if (format24Requested) { - mFormat = abc(mFormat24, mFormat12, ld.timeFormat24); + mFormat = abc(mFormat24, mFormat12, ld.timeFormat_Hm); } else { - mFormat = abc(mFormat12, mFormat24, ld.timeFormat12); + mFormat = abc(mFormat12, mFormat24, ld.timeFormat_hm); } boolean hadSeconds = mHasSeconds; diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 7dc64bd..dd8280b 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -93,7 +93,6 @@ import android.text.style.URLSpan; import android.text.style.UpdateAppearance; import android.text.util.Linkify; import android.util.AttributeSet; -import android.util.FloatMath; import android.util.Log; import android.util.TypedValue; import android.view.AccessibilityIterators.TextSegmentIterator; @@ -3820,7 +3819,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // Display the error later, after the first layout pass post(new Runnable() { public void run() { - setError(error); + if (mEditor == null || !mEditor.mErrorWasChanged) { + setError(error); + } } }); } @@ -4800,7 +4801,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * make sure the entire cursor gets invalidated instead of * sometimes missing half a pixel. */ - float thick = FloatMath.ceil(mTextPaint.getStrokeWidth()); + float thick = (float) Math.ceil(mTextPaint.getStrokeWidth()); if (thick < 1.0f) { thick = 1.0f; } @@ -4810,10 +4811,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // mHighlightPath is guaranteed to be non null at that point. mHighlightPath.computeBounds(TEMP_RECTF, false); - invalidate((int) FloatMath.floor(horizontalPadding + TEMP_RECTF.left - thick), - (int) FloatMath.floor(verticalPadding + TEMP_RECTF.top - thick), - (int) FloatMath.ceil(horizontalPadding + TEMP_RECTF.right + thick), - (int) FloatMath.ceil(verticalPadding + TEMP_RECTF.bottom + thick)); + invalidate((int) Math.floor(horizontalPadding + TEMP_RECTF.left - thick), + (int) Math.floor(verticalPadding + TEMP_RECTF.top - thick), + (int) Math.ceil(horizontalPadding + TEMP_RECTF.right + thick), + (int) Math.ceil(verticalPadding + TEMP_RECTF.bottom + thick)); } } else { for (int i = 0; i < mEditor.mCursorCount; i++) { @@ -6507,7 +6508,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener max = Math.max(max, layout.getLineWidth(i)); } - return (int) FloatMath.ceil(max); + return (int) Math.ceil(max); } /** @@ -6584,7 +6585,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (boring == null || boring == UNKNOWN_BORING) { if (des < 0) { - des = (int) FloatMath.ceil(Layout.getDesiredWidth(mTransformed, mTextPaint)); + des = (int) Math.ceil(Layout.getDesiredWidth(mTransformed, mTextPaint)); } width = des; } else { @@ -6614,7 +6615,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (hintBoring == null || hintBoring == UNKNOWN_BORING) { if (hintDes < 0) { - hintDes = (int) FloatMath.ceil(Layout.getDesiredWidth(mHint, mTextPaint)); + hintDes = (int) Math.ceil(Layout.getDesiredWidth(mHint, mTextPaint)); } hintWidth = hintDes; } else { @@ -6920,8 +6921,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * keep leading edge in view. */ - int left = (int) FloatMath.floor(layout.getLineLeft(line)); - int right = (int) FloatMath.ceil(layout.getLineRight(line)); + int left = (int) Math.floor(layout.getLineLeft(line)); + int right = (int) Math.ceil(layout.getLineRight(line)); if (right - left < hspace) { scrollx = (right + left) / 2 - hspace / 2; @@ -6933,10 +6934,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } } else if (a == Layout.Alignment.ALIGN_RIGHT) { - int right = (int) FloatMath.ceil(layout.getLineRight(line)); + int right = (int) Math.ceil(layout.getLineRight(line)); scrollx = right - hspace; } else { // a == Layout.Alignment.ALIGN_LEFT (will also be the default) - scrollx = (int) FloatMath.floor(layout.getLineLeft(line)); + scrollx = (int) Math.floor(layout.getLineLeft(line)); } if (ht < vspace) { @@ -7011,8 +7012,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener final int top = layout.getLineTop(line); final int bottom = layout.getLineTop(line + 1); - int left = (int) FloatMath.floor(layout.getLineLeft(line)); - int right = (int) FloatMath.ceil(layout.getLineRight(line)); + int left = (int) Math.floor(layout.getLineLeft(line)); + int right = (int) Math.ceil(layout.getLineRight(line)); int ht = layout.getHeight(); int hspace = mRight - mLeft - getCompoundPaddingLeft() - getCompoundPaddingRight(); |