diff options
Diffstat (limited to 'core')
54 files changed, 691 insertions, 1552 deletions
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java index 6394299..86da673 100644 --- a/core/java/android/animation/ValueAnimator.java +++ b/core/java/android/animation/ValueAnimator.java @@ -1027,6 +1027,8 @@ public class ValueAnimator extends Animator { long currentPlayTime = currentTime - mStartTime; long timeLeft = mDuration - currentPlayTime; mStartTime = currentTime - timeLeft; + } else if (mStarted) { + end(); } else { start(true); } diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index 653559d..370db31 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -1917,7 +1917,8 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM data.enforceInterface(IActivityManager.descriptor); int pid = data.readInt(); boolean aboveSystem = data.readInt() != 0; - long res = inputDispatchingTimedOut(pid, aboveSystem); + String reason = data.readString(); + long res = inputDispatchingTimedOut(pid, aboveSystem, reason); reply.writeNoException(); reply.writeLong(res); return true; @@ -1936,8 +1937,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); Bundle extras = data.readBundle(); - int index = data.readInt(); - reportAssistContextExtras(token, extras, index); + reportAssistContextExtras(token, extras); reply.writeNoException(); return true; } @@ -4462,12 +4462,14 @@ class ActivityManagerProxy implements IActivityManager reply.recycle(); } - public long inputDispatchingTimedOut(int pid, boolean aboveSystem) throws RemoteException { + public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason) + throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeInt(pid); data.writeInt(aboveSystem ? 1 : 0); + data.writeString(reason); mRemote.transact(INPUT_DISPATCHING_TIMED_OUT_TRANSACTION, data, reply, 0); reply.readException(); long res = reply.readInt(); @@ -4489,14 +4491,13 @@ class ActivityManagerProxy implements IActivityManager return res; } - public void reportAssistContextExtras(IBinder token, Bundle extras, int index) + public void reportAssistContextExtras(IBinder token, Bundle extras) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(token); data.writeBundle(extras); - data.writeInt(index); mRemote.transact(REPORT_ASSIST_CONTEXT_EXTRAS_TRANSACTION, data, reply, 0); reply.readException(); data.recycle(); diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 018fbe0..209514a 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -528,7 +528,6 @@ public final class ActivityThread { IBinder activityToken; IBinder requestToken; int requestType; - int index; } private native void dumpGraphicsInfo(FileDescriptor fd); @@ -1194,12 +1193,11 @@ public final class ActivityThread { @Override public void requestAssistContextExtras(IBinder activityToken, IBinder requestToken, - int requestType, int index) { + int requestType) { RequestAssistContextExtras cmd = new RequestAssistContextExtras(); cmd.activityToken = activityToken; cmd.requestToken = requestToken; cmd.requestType = requestType; - cmd.index = index; queueOrSendMessage(H.REQUEST_ASSIST_CONTEXT_EXTRAS, cmd); } @@ -2278,18 +2276,13 @@ public final class ActivityThread { if (r != null) { r.activity.getApplication().dispatchOnProvideAssistData(r.activity, data); r.activity.onProvideAssistData(data); - } else { - Service service = mServices.get(cmd.activityToken); - if (service != null) { - service.onProvideAssistData(data); - } } if (data.isEmpty()) { data = null; } IActivityManager mgr = ActivityManagerNative.getDefault(); try { - mgr.reportAssistContextExtras(cmd.requestToken, data, cmd.index); + mgr.reportAssistContextExtras(cmd.requestToken, data); } catch (RemoteException e) { } } diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 19a028d..3e4795c 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -185,11 +185,11 @@ public class AppOpsManager { OP_CALL_PHONE, OP_READ_SMS, OP_WRITE_SMS, - OP_READ_SMS, - OP_READ_SMS, - OP_READ_SMS, - OP_READ_SMS, - OP_WRITE_SMS, + OP_RECEIVE_SMS, + OP_RECEIVE_SMS, + OP_RECEIVE_SMS, + OP_RECEIVE_SMS, + OP_SEND_SMS, OP_READ_SMS, OP_WRITE_SMS, OP_WRITE_SETTINGS, @@ -575,6 +575,10 @@ public class AppOpsManager { } } + private String buildSecurityExceptionMsg(int op, int uid, String packageName) { + return packageName + " from uid " + uid + " not allowed to perform " + sOpNames[op]; + } + /** * Do a quick check for whether an application might be able to perform an operation. * This is <em>not</em> a security check; you must use {@link #noteOp(int, int, String)} @@ -595,7 +599,7 @@ public class AppOpsManager { try { int mode = mService.checkOperation(op, uid, packageName); if (mode == MODE_ERRORED) { - throw new SecurityException("Operation not allowed"); + throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName)); } return mode; } catch (RemoteException e) { @@ -650,7 +654,7 @@ public class AppOpsManager { try { int mode = mService.noteOperation(op, uid, packageName); if (mode == MODE_ERRORED) { - throw new SecurityException("Operation not allowed"); + throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName)); } return mode; } catch (RemoteException e) { @@ -672,7 +676,7 @@ public class AppOpsManager { /** @hide */ public int noteOp(int op) { - return noteOp(op, Process.myUid(), mContext.getBasePackageName()); + return noteOp(op, Process.myUid(), mContext.getOpPackageName()); } /** @hide */ @@ -710,7 +714,7 @@ public class AppOpsManager { try { int mode = mService.startOperation(getToken(mService), op, uid, packageName); if (mode == MODE_ERRORED) { - throw new SecurityException("Operation not allowed"); + throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName)); } return mode; } catch (RemoteException e) { @@ -732,7 +736,7 @@ public class AppOpsManager { /** @hide */ public int startOp(int op) { - return startOp(op, Process.myUid(), mContext.getBasePackageName()); + return startOp(op, Process.myUid(), mContext.getOpPackageName()); } /** @@ -749,6 +753,6 @@ public class AppOpsManager { } public void finishOp(int op) { - finishOp(op, Process.myUid(), mContext.getBasePackageName()); + finishOp(op, Process.myUid(), mContext.getOpPackageName()); } } diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index ab2739d..e522b78 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -1275,7 +1275,7 @@ final class ApplicationPackageManager extends PackageManager { int newState, int flags) { try { mPM.setApplicationEnabledSetting(packageName, newState, flags, - mContext.getUserId(), mContext.getBasePackageName()); + mContext.getUserId(), mContext.getOpPackageName()); } catch (RemoteException e) { // Should never happen! } diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java index c0080be..a4e80e5 100644 --- a/core/java/android/app/ApplicationThreadNative.java +++ b/core/java/android/app/ApplicationThreadNative.java @@ -606,8 +606,7 @@ public abstract class ApplicationThreadNative extends Binder IBinder activityToken = data.readStrongBinder(); IBinder requestToken = data.readStrongBinder(); int requestType = data.readInt(); - int index = data.readInt(); - requestAssistContextExtras(activityToken, requestToken, requestType, index); + requestAssistContextExtras(activityToken, requestToken, requestType); reply.writeNoException(); return true; } @@ -1243,13 +1242,12 @@ class ApplicationThreadProxy implements IApplicationThread { @Override public void requestAssistContextExtras(IBinder activityToken, IBinder requestToken, - int requestType, int index) throws RemoteException { + int requestType) throws RemoteException { Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); data.writeStrongBinder(activityToken); data.writeStrongBinder(requestToken); data.writeInt(requestType); - data.writeInt(index); mRemote.transact(REQUEST_ASSIST_CONTEXT_EXTRAS_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); data.recycle(); diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 7ff7562..8e9f3bb 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -47,6 +47,7 @@ import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; +import android.hardware.ConsumerIrManager; import android.hardware.ISerialManager; import android.hardware.SerialManager; import android.hardware.SystemSensorManager; @@ -183,6 +184,7 @@ class ContextImpl extends Context { /*package*/ LoadedApk mPackageInfo; private String mBasePackageName; + private String mOpPackageName; private Resources mResources; /*package*/ ActivityThread mMainThread; private Context mOuterContext; @@ -579,6 +581,11 @@ class ContextImpl extends Context { return new PrintManager(ctx.getOuterContext(), service, UserHandle.myUserId(), UserHandle.getAppId(Process.myUid())); }}); + + registerService(CONSUMER_IR_SERVICE, new ServiceFetcher() { + public Object createService(ContextImpl ctx) { + return new ConsumerIrManager(ctx); + }}); } static ContextImpl getImpl(Context context) { @@ -679,6 +686,12 @@ class ContextImpl extends Context { return mBasePackageName != null ? mBasePackageName : getPackageName(); } + /** @hide */ + @Override + public String getOpPackageName() { + return mOpPackageName != null ? mOpPackageName : getBasePackageName(); + } + @Override public ApplicationInfo getApplicationInfo() { if (mPackageInfo != null) { @@ -1961,6 +1974,7 @@ class ContextImpl extends Context { public ContextImpl(ContextImpl context) { mPackageInfo = context.mPackageInfo; mBasePackageName = context.mBasePackageName; + mOpPackageName = context.mOpPackageName; mResources = context.mResources; mMainThread = context.mMainThread; mContentResolver = context.mContentResolver; @@ -1977,7 +1991,21 @@ class ContextImpl extends Context { final void init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread, Resources container, String basePackageName, UserHandle user) { mPackageInfo = packageInfo; - mBasePackageName = basePackageName != null ? basePackageName : packageInfo.mPackageName; + if (basePackageName != null) { + mBasePackageName = mOpPackageName = basePackageName; + } else { + mBasePackageName = packageInfo.mPackageName; + ApplicationInfo ainfo = packageInfo.getApplicationInfo(); + if (ainfo.uid == Process.SYSTEM_UID && ainfo.uid != Process.myUid()) { + // Special case: system components allow themselves to be loaded in to other + // processes. For purposes of app ops, we must then consider the context as + // belonging to the package of this process, not the system itself, otherwise + // the package+uid verifications in app ops will fail. + mOpPackageName = ActivityThread.currentPackageName(); + } else { + mOpPackageName = mBasePackageName; + } + } mResources = mPackageInfo.getResources(mainThread); mResourcesManager = ResourcesManager.getInstance(); @@ -2011,6 +2039,7 @@ class ContextImpl extends Context { final void init(Resources resources, ActivityThread mainThread, UserHandle user) { mPackageInfo = null; mBasePackageName = null; + mOpPackageName = null; mResources = resources; mMainThread = mainThread; mContentResolver = new ApplicationContentResolver(this, mainThread, user); diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index af9a245..b2ae298 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -384,12 +384,12 @@ public interface IActivityManager extends IInterface { public void requestBugReport() throws RemoteException; - public long inputDispatchingTimedOut(int pid, boolean aboveSystem) throws RemoteException; + public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason) + throws RemoteException; public Bundle getAssistContextExtras(int requestType) throws RemoteException; - public void reportAssistContextExtras(IBinder token, Bundle extras, int index) - throws RemoteException; + public void reportAssistContextExtras(IBinder token, Bundle extras) throws RemoteException; public void killUid(int uid, String reason) throws RemoteException; diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java index 01a0a91..058b975 100644 --- a/core/java/android/app/IApplicationThread.java +++ b/core/java/android/app/IApplicationThread.java @@ -133,8 +133,8 @@ public interface IApplicationThread extends IInterface { void dumpGfxInfo(FileDescriptor fd, String[] args) throws RemoteException; void dumpDbInfo(FileDescriptor fd, String[] args) throws RemoteException; void unstableProviderDied(IBinder provider) throws RemoteException; - void requestAssistContextExtras(IBinder activityToken, IBinder requestToken, int requestType, - int index) throws RemoteException; + void requestAssistContextExtras(IBinder activityToken, IBinder requestToken, int requestType) + throws RemoteException; void scheduleTranslucentConversionComplete(IBinder token, boolean timeout) throws RemoteException; void setProcessState(int state) throws RemoteException; diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index dbafc78..3ee4306 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -133,7 +133,7 @@ public class NotificationManager } if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")"); try { - service.enqueueNotificationWithTag(pkg, mContext.getBasePackageName(), tag, id, + service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id, notification, idOut, UserHandle.myUserId()); if (id != idOut[0]) { Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]); @@ -158,7 +158,7 @@ public class NotificationManager } if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")"); try { - service.enqueueNotificationWithTag(pkg, mContext.getBasePackageName(), tag, id, + service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id, notification, idOut, user.getIdentifier()); if (id != idOut[0]) { Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]); diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java index 1254bac..3967740 100644 --- a/core/java/android/app/Service.java +++ b/core/java/android/app/Service.java @@ -23,7 +23,6 @@ import android.content.ContextWrapper; import android.content.Context; import android.content.res.Configuration; import android.os.Build; -import android.os.Bundle; import android.os.RemoteException; import android.os.IBinder; import android.util.Log; @@ -308,18 +307,6 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac } /** - * This is called on foreground services when the user is requesting an assist, to build a - * full {@link Intent#ACTION_ASSIST} Intent with all of the context of the current - * running foreground services. You can override this method to place into the bundle - * anything you would like to appear as an item in the - * {@link Intent#EXTRA_ASSIST_SERVICES_CONTEXTS} part of the assist Intent. - * This method will not be called if this service is not in the foreground. - * The default implementation does nothing. - */ - public void onProvideAssistData(Bundle data) { - } - - /** * @deprecated Implement {@link #onStartCommand(Intent, int, int)} instead. */ @Deprecated diff --git a/core/java/android/content/ClipboardManager.java b/core/java/android/content/ClipboardManager.java index 69f9d4a..73e6fd0 100644 --- a/core/java/android/content/ClipboardManager.java +++ b/core/java/android/content/ClipboardManager.java @@ -122,7 +122,7 @@ public class ClipboardManager extends android.text.ClipboardManager { if (clip != null) { clip.prepareToLeaveProcess(); } - getService().setPrimaryClip(clip, mContext.getBasePackageName()); + getService().setPrimaryClip(clip, mContext.getOpPackageName()); } catch (RemoteException e) { } } @@ -132,7 +132,7 @@ public class ClipboardManager extends android.text.ClipboardManager { */ public ClipData getPrimaryClip() { try { - return getService().getPrimaryClip(mContext.getBasePackageName()); + return getService().getPrimaryClip(mContext.getOpPackageName()); } catch (RemoteException e) { return null; } @@ -144,7 +144,7 @@ public class ClipboardManager extends android.text.ClipboardManager { */ public ClipDescription getPrimaryClipDescription() { try { - return getService().getPrimaryClipDescription(mContext.getBasePackageName()); + return getService().getPrimaryClipDescription(mContext.getOpPackageName()); } catch (RemoteException e) { return null; } @@ -155,7 +155,7 @@ public class ClipboardManager extends android.text.ClipboardManager { */ public boolean hasPrimaryClip() { try { - return getService().hasPrimaryClip(mContext.getBasePackageName()); + return getService().hasPrimaryClip(mContext.getOpPackageName()); } catch (RemoteException e) { return false; } @@ -166,7 +166,7 @@ public class ClipboardManager extends android.text.ClipboardManager { if (mPrimaryClipChangedListeners.size() == 0) { try { getService().addPrimaryClipChangedListener( - mPrimaryClipChangedServiceListener, mContext.getBasePackageName()); + mPrimaryClipChangedServiceListener, mContext.getOpPackageName()); } catch (RemoteException e) { } } @@ -213,7 +213,7 @@ public class ClipboardManager extends android.text.ClipboardManager { */ public boolean hasText() { try { - return getService().hasClipboardText(mContext.getBasePackageName()); + return getService().hasClipboardText(mContext.getOpPackageName()); } catch (RemoteException e) { return false; } diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java index 3438419..0a1d3f9 100644 --- a/core/java/android/content/ContentProvider.java +++ b/core/java/android/content/ContentProvider.java @@ -918,8 +918,10 @@ public abstract class ContentProvider implements ComponentCallbacks2 { * * @param url The Uri to remove any canonicalization from. * - * @return Return the non-canonical representation of <var>url</var>, or return - * the <var>url</var> as-is if there is nothing to do. Never return null. + * @return Return the non-canonical representation of <var>url</var>, return + * the <var>url</var> as-is if there is nothing to do, or return null if + * the data identified by the canonical representation can not be found in + * the current environment. */ public Uri uncanonicalize(Uri url) { return url; diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java index e914604..f250029 100644 --- a/core/java/android/content/ContentResolver.java +++ b/core/java/android/content/ContentResolver.java @@ -261,7 +261,7 @@ public abstract class ContentResolver { public ContentResolver(Context context) { mContext = context != null ? context : ActivityThread.currentApplication(); - mPackageName = mContext.getBasePackageName(); + mPackageName = mContext.getOpPackageName(); } /** @hide */ @@ -548,14 +548,16 @@ public abstract class ContentResolver { * it to its local non-canonical form. This can be useful in some cases where * you know that you will only be using the Uri in the current environment and * want to avoid any possible overhead when using it with the content - * provider. + * provider or want to verify that the referenced data exists at all in the + * new environment. * * @param url The canonical {@link Uri} that is to be convered back to its * non-canonical form. * - * @return Returns the non-canonical representation of <var>url</var>. This - * function never returns null; if there is no conversion to be done, it returns - * the same Uri that was provided. + * @return Returns the non-canonical representation of <var>url</var>. This will + * return null if data identified by the canonical Uri can not be found in + * the current environment; callers must always check for null and deal with + * that by appropriately falling back to an alternative. * * @see #canonicalize */ diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 8df5bee..92a9c7c 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -435,6 +435,13 @@ public abstract class Context { /** @hide Return the name of the base context this context is derived from. */ public abstract String getBasePackageName(); + /** @hide Return the package name that should be used for app ops calls from + * this context. This is the same as {@link #getBasePackageName()} except in + * cases where system components are loaded into other app processes, in which + * case this will be the name of the primary package in that process (so that app + * ops uid verification will work with the name). */ + public abstract String getOpPackageName(); + /** Return the full application info for this context's package. */ public abstract ApplicationInfo getApplicationInfo(); @@ -2394,6 +2401,16 @@ public abstract class Context { public static final String PRINT_SERVICE = "print"; /** + * Use with {@link #getSystemService} to retrieve a + * {@link android.hardware.ConsumerIrManager} for transmitting infrared + * signals from the device. + * + * @see #getSystemService + * @see android.hardware.ConsumerIrManager + */ + public static final String CONSUMER_IR_SERVICE = "consumer_ir"; + + /** * Determine whether the given permission is allowed for a particular * process and user ID running in the system. * diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index e09d367..a708dad 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -141,6 +141,12 @@ public class ContextWrapper extends Context { return mBase.getBasePackageName(); } + /** @hide */ + @Override + public String getOpPackageName() { + return mBase.getOpPackageName(); + } + @Override public ApplicationInfo getApplicationInfo() { return mBase.getApplicationInfo(); diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 2f2aae4..7925123 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -1153,9 +1153,8 @@ public class Intent implements Parcelable, Cloneable { /** * Activity Action: Perform assist action. * <p> - * Input: {@link #EXTRA_ASSIST_PACKAGE}, {@link #EXTRA_ASSIST_CONTEXT}, - * {@link #EXTRA_ASSIST_SERVICES_PACKAGES}, and {@link #EXTRA_ASSIST_SERVICES_CONTEXTS} can - * provide additional optional contextual information about where the user was when they + * Input: {@link #EXTRA_ASSIST_PACKAGE}, {@link #EXTRA_ASSIST_CONTEXT}, can provide + * additional optional contextual information about where the user was when they * requested the assist. * Output: nothing. */ @@ -1165,52 +1164,31 @@ public class Intent implements Parcelable, Cloneable { /** * Activity Action: Perform voice assist action. * <p> - * Input: {@link #EXTRA_ASSIST_PACKAGE}, {@link #EXTRA_ASSIST_CONTEXT}, - * {@link #EXTRA_ASSIST_SERVICES_PACKAGES}, and {@link #EXTRA_ASSIST_SERVICES_CONTEXTS} can - * provide additional optional contextual information about where the user was when they + * Input: {@link #EXTRA_ASSIST_PACKAGE}, {@link #EXTRA_ASSIST_CONTEXT}, can provide + * additional optional contextual information about where the user was when they * requested the voice assist. * Output: nothing. + * @hide */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_VOICE_ASSIST = "android.intent.action.VOICE_ASSIST"; /** - * An optional field on {@link #ACTION_ASSIST} and {@link #ACTION_VOICE_ASSIST} - * containing the name of the current foreground application package at the time - * the assist was invoked. + * An optional field on {@link #ACTION_ASSIST} containing the name of the current foreground + * application package at the time the assist was invoked. */ public static final String EXTRA_ASSIST_PACKAGE = "android.intent.extra.ASSIST_PACKAGE"; /** - * An optional field on {@link #ACTION_ASSIST} and {@link #ACTION_VOICE_ASSIST} - * containing additional contextual information supplied by the current - * foreground app at the time of the assist request. This is a {@link Bundle} of - * additional data. + * An optional field on {@link #ACTION_ASSIST} and containing additional contextual + * information supplied by the current foreground app at the time of the assist request. + * This is a {@link Bundle} of additional data. */ public static final String EXTRA_ASSIST_CONTEXT = "android.intent.extra.ASSIST_CONTEXT"; /** - * An optional field on {@link #ACTION_ASSIST} and {@link #ACTION_VOICE_ASSIST} - * containing the application package names of foreground services at the time - * of the assist request. This is an array of {@link String}s, with one entry - * per service. - */ - public static final String EXTRA_ASSIST_SERVICES_PACKAGES - = "android.intent.extra.ASSIST_SERVICES_PACKAGES"; - - /** - * An optional field on {@link #ACTION_ASSIST} and {@link #ACTION_VOICE_ASSIST} - * containing additional contextual information supplied by the current - * foreground services at the time of the assist request. This is an array - * of {@link Bundle}s of additional data, with one {@link Bundle} per service. - */ - public static final String EXTRA_ASSIST_SERVICES_CONTEXTS - = "android.intent.extra.ASSIST_SERVICES_CONTEXTS"; - - - /** * Activity Action: List all available applications * <p>Input: Nothing. * <p>Output: nothing. diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 6760f49..4494e69 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -3015,11 +3015,6 @@ public class PackageParser { s.info.flags = 0; if (sa.getBoolean( - com.android.internal.R.styleable.AndroidManifestService_provideAssistData, - false)) { - s.info.flags |= ServiceInfo.FLAG_PROVIDE_ASSIST_DATA; - } - if (sa.getBoolean( com.android.internal.R.styleable.AndroidManifestService_stopWithTask, false)) { s.info.flags |= ServiceInfo.FLAG_STOP_WITH_TASK; diff --git a/core/java/android/content/pm/ServiceInfo.java b/core/java/android/content/pm/ServiceInfo.java index 3dc8717..796c2a4 100644 --- a/core/java/android/content/pm/ServiceInfo.java +++ b/core/java/android/content/pm/ServiceInfo.java @@ -49,14 +49,6 @@ public class ServiceInfo extends ComponentInfo public static final int FLAG_ISOLATED_PROCESS = 0x0002; /** - * Bit in {@link #flags}: If set, - * {@link android.app.Service#onProvideAssistData(android.os.Bundle)} will - * be called on the service when it is running in the foreground. Set from - * the {@link android.R.attr#provideAssistData} attribute. - */ - public static final int FLAG_PROVIDE_ASSIST_DATA = 0x0004; - - /** * Bit in {@link #flags}: If set, a single instance of the service will * run for all users on the device. Set from the * {@link android.R.attr#singleUser} attribute. diff --git a/core/java/android/hardware/ConsumerIrManager.java b/core/java/android/hardware/ConsumerIrManager.java new file mode 100644 index 0000000..baa743c --- /dev/null +++ b/core/java/android/hardware/ConsumerIrManager.java @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2013 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.hardware; + +import android.content.Context; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.util.Log; + +/** + * Class that operates consumer infrared on the device. + * + * <p> + * To obtain an instance of the system infrared transmitter, call + * {@link Context#getSystemService} with {@link Context#CONSUMER_IR} as the argument. + * </p> + */ +public final class ConsumerIrManager { + private static final String TAG = "ConsumerIr"; + + private final String mPackageName; + private final IConsumerIrService mService; + + /** + * @hide to prevent subclassing from outside of the framework + */ + public ConsumerIrManager(Context context) { + mPackageName = context.getPackageName(); + mService = IConsumerIrService.Stub.asInterface( + ServiceManager.getService(Context.CONSUMER_IR_SERVICE)); + } + + /** + * Check whether the device has an infrared emitter. + * + * @return true if the device has an infrared emitter, else false. + */ + public boolean hasIrEmitter() { + if (mService == null) { + Log.w(TAG, "no consumer ir service."); + return false; + } + + try { + return mService.hasIrEmitter(); + } catch (RemoteException e) { + } + return false; + } + + /** + * Tansmit and infrared pattern + * <p> + * This method is synchronous; when it returns the pattern has + * been transmitted. Only patterns shorter than 2 seconds will + * be transmitted. + * </p> + * + * @param carrierFrequency The IR carrier frequency in Hertz. + * @param pattern The alternating on/off pattern in microseconds to transmit. + */ + public void transmit(int carrierFrequency, int[] pattern) { + if (mService == null) { + Log.w(TAG, "failed to transmit; no consumer ir service."); + return; + } + + try { + mService.transmit(mPackageName, carrierFrequency, pattern); + } catch (RemoteException e) { + Log.w(TAG, "failed to transmit.", e); + } + } + + /** + * Represents a range of carrier frequencies (inclusive) on which the + * infrared transmitter can transmit + */ + public final class CarrierFrequencyRange { + private final int mMinFrequency; + private final int mMaxFrequency; + + /** + * Create a segment of a carrier frequency range. + * + * @param min The minimum transmittable frequency in this range segment. + * @param max The maximum transmittable frequency in this range segment. + */ + public CarrierFrequencyRange(int min, int max) { + mMinFrequency = min; + mMaxFrequency = max; + } + + /** + * Get the minimum (inclusive) frequency in this range segment. + */ + public int getMinFrequency() { + return mMinFrequency; + } + + /** + * Get the maximum (inclusive) frequency in this range segment. + */ + public int getMaxFrequency() { + return mMaxFrequency; + } + }; + + /** + * Query the infrared transmitter's supported carrier frequencies + * + * @return an array of {@link #CarrierFreqRange} objects representing + * the ranges that the transmitter can support, or null if there was + * an error communicating with the Consumer IR Service. + */ + public CarrierFrequencyRange[] getCarrierFrequencies() { + if (mService == null) { + Log.w(TAG, "no consumer ir service."); + return null; + } + + try { + int[] freqs = mService.getCarrierFrequencies(); + if (freqs.length % 2 != 0) { + Log.w(TAG, "consumer ir service returned an uneven number of frequencies."); + return null; + } + CarrierFrequencyRange[] range = new CarrierFrequencyRange[freqs.length / 2]; + + for (int i = 0; i < freqs.length; i += 2) { + range[i / 2] = new CarrierFrequencyRange(freqs[i], freqs[i+1]); + } + return range; + } catch (RemoteException e) { + } + return null; + } + +} diff --git a/core/java/android/hardware/IConsumerIrService.aidl b/core/java/android/hardware/IConsumerIrService.aidl new file mode 100644 index 0000000..c79bd19 --- /dev/null +++ b/core/java/android/hardware/IConsumerIrService.aidl @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2013, 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.hardware; + +/** {@hide} */ +interface IConsumerIrService +{ + boolean hasIrEmitter(); + void transmit(String packageName, int carrierFrequency, in int[] pattern); + int[] getCarrierFrequencies(); +} + diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java index 8903b4a..ff9282e 100644 --- a/core/java/android/hardware/camera2/CameraManager.java +++ b/core/java/android/hardware/camera2/CameraManager.java @@ -55,7 +55,7 @@ public final class CameraManager { private final ICameraService mCameraService; private ArrayList<String> mDeviceIdList; - private HashSet<CameraListener> mListenerSet = new HashSet<CameraListener>(); + private final HashSet<CameraListener> mListenerSet = new HashSet<CameraListener>(); private final Context mContext; private final Object mLock = new Object(); @@ -332,7 +332,7 @@ public final class CameraManager { Integer oldStatus = mDeviceStatus.put(id, status); - if (oldStatus == status) { + if (oldStatus != null && oldStatus == status) { Log.v(TAG, String.format( "Device status changed to 0x%x, which is what it already was", status)); diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 4cf38b6..c78a973 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -1476,4 +1476,20 @@ public class ConnectivityManager { } catch (RemoteException e) { } } + + /** + * Set the value for enabling/disabling airplane mode + * + * @param enable whether to enable airplane mode or not + * + * <p>This method requires the call to hold the permission + * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}. + * @hide + */ + public void setAirplaneMode(boolean enable) { + try { + mService.setAirplaneMode(enable); + } catch (RemoteException e) { + } + } } diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index 826f90c..c1da2e3 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -150,4 +150,6 @@ interface IConnectivityManager LinkQualityInfo[] getAllLinkQualityInfo(); void setProvisioningNotificationVisible(boolean visible, int networkType, in String extraInfo, in String url); + + void setAirplaneMode(boolean enable); } diff --git a/core/java/android/nfc/cardemulation/ApduServiceInfo.java b/core/java/android/nfc/cardemulation/ApduServiceInfo.java index 41c6603..40a3612 100644 --- a/core/java/android/nfc/cardemulation/ApduServiceInfo.java +++ b/core/java/android/nfc/cardemulation/ApduServiceInfo.java @@ -22,6 +22,7 @@ import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; +import android.content.res.Resources.NotFoundException; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.graphics.drawable.Drawable; @@ -80,10 +81,15 @@ public final class ApduServiceInfo implements Parcelable { final boolean mRequiresDeviceUnlock; /** + * The id of the service banner specified in XML. + */ + final int mBannerResourceId; + + /** * @hide */ public ApduServiceInfo(ResolveInfo info, boolean onHost, String description, - ArrayList<AidGroup> aidGroups, boolean requiresUnlock) { + ArrayList<AidGroup> aidGroups, boolean requiresUnlock, int bannerResource) { this.mService = info; this.mDescription = description; this.mAidGroups = aidGroups; @@ -95,6 +101,7 @@ public final class ApduServiceInfo implements Parcelable { this.mCategoryToGroup.put(aidGroup.category, aidGroup); this.mAids.addAll(aidGroup.aids); } + this.mBannerResourceId = bannerResource; } public ApduServiceInfo(PackageManager pm, ResolveInfo info, boolean onHost) @@ -105,12 +112,8 @@ public final class ApduServiceInfo implements Parcelable { if (onHost) { parser = si.loadXmlMetaData(pm, HostApduService.SERVICE_META_DATA); if (parser == null) { - Log.d(TAG, "Didn't find service meta-data, trying legacy."); - parser = si.loadXmlMetaData(pm, HostApduService.OLD_SERVICE_META_DATA); - if (parser == null) { - throw new XmlPullParserException("No " + HostApduService.SERVICE_META_DATA + - " meta-data"); - } + throw new XmlPullParserException("No " + HostApduService.SERVICE_META_DATA + + " meta-data"); } } else { parser = si.loadXmlMetaData(pm, OffHostApduService.SERVICE_META_DATA); @@ -145,6 +148,9 @@ public final class ApduServiceInfo implements Parcelable { mRequiresDeviceUnlock = sa.getBoolean( com.android.internal.R.styleable.HostApduService_requireDeviceUnlock, false); + mBannerResourceId = sa.getResourceId( + com.android.internal.R.styleable.HostApduService_apduServiceBanner, -1); + sa.recycle(); } else { TypedArray sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.OffHostApduService); @@ -152,6 +158,9 @@ public final class ApduServiceInfo implements Parcelable { mDescription = sa.getString( com.android.internal.R.styleable.OffHostApduService_description); mRequiresDeviceUnlock = false; + mBannerResourceId = sa.getResourceId( + com.android.internal.R.styleable.HostApduService_apduServiceBanner, -1); + sa.recycle(); } mAidGroups = new ArrayList<AidGroup>(); @@ -187,6 +196,7 @@ public final class ApduServiceInfo implements Parcelable { } else { currentGroup = new AidGroup(groupCategory, groupDescription); } + groupAttrs.recycle(); } else if (eventType == XmlPullParser.END_TAG && "aid-group".equals(tagName) && currentGroup != null) { if (currentGroup.aids.size() > 0) { @@ -210,6 +220,7 @@ public final class ApduServiceInfo implements Parcelable { } else { Log.e(TAG, "Ignoring invalid or duplicate aid: " + aid); } + a.recycle(); } } } catch (NameNotFoundException e) { @@ -252,6 +263,21 @@ public final class ApduServiceInfo implements Parcelable { return mService.loadIcon(pm); } + public Drawable loadBanner(PackageManager pm) { + Resources res; + try { + res = pm.getResourcesForApplication(mService.serviceInfo.packageName); + Drawable banner = res.getDrawable(mBannerResourceId); + return banner; + } catch (NotFoundException e) { + Log.e(TAG, "Could not load banner."); + return null; + } catch (NameNotFoundException e) { + Log.e(TAG, "Could not load banner."); + return null; + } + } + static boolean isValidAid(String aid) { if (aid == null) return false; @@ -306,6 +332,7 @@ public final class ApduServiceInfo implements Parcelable { dest.writeTypedList(mAidGroups); } dest.writeInt(mRequiresDeviceUnlock ? 1 : 0); + dest.writeInt(mBannerResourceId); }; public static final Parcelable.Creator<ApduServiceInfo> CREATOR = @@ -321,7 +348,8 @@ public final class ApduServiceInfo implements Parcelable { source.readTypedList(aidGroups, AidGroup.CREATOR); } boolean requiresUnlock = (source.readInt() != 0) ? true : false; - return new ApduServiceInfo(info, onHost, description, aidGroups, requiresUnlock); + int bannerResource = source.readInt(); + return new ApduServiceInfo(info, onHost, description, aidGroups, requiresUnlock, bannerResource); } @Override diff --git a/core/java/android/nfc/cardemulation/CardEmulationManager.java b/core/java/android/nfc/cardemulation/CardEmulationManager.java deleted file mode 100644 index 124ea1c..0000000 --- a/core/java/android/nfc/cardemulation/CardEmulationManager.java +++ /dev/null @@ -1,347 +0,0 @@ -/* - * Copyright (C) 2013 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.nfc.cardemulation; - -import android.annotation.SdkConstant; -import android.annotation.SdkConstant.SdkConstantType; -import android.app.ActivityThread; -import android.content.ComponentName; -import android.content.Context; -import android.content.pm.IPackageManager; -import android.content.pm.PackageManager; -import android.nfc.INfcCardEmulation; -import android.nfc.NfcAdapter; -import android.os.RemoteException; -import android.os.UserHandle; -import android.provider.Settings; -import android.util.Log; - -import java.util.HashMap; -import java.util.List; - -/** - * TODO Remove when calling .apks are upgraded - * @hide - */ -public final class CardEmulationManager { - static final String TAG = "CardEmulationManager"; - - /** - * Activity action: ask the user to change the default - * card emulation service for a certain category. This will - * show a dialog that asks the user whether he wants to - * replace the current default service with the service - * identified with the ComponentName specified in - * {@link #EXTRA_SERVICE_COMPONENT}, for the category - * specified in {@link #EXTRA_CATEGORY} - */ - @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) - public static final String ACTION_CHANGE_DEFAULT = - "android.nfc.cardemulation.ACTION_CHANGE_DEFAULT"; - - /** - * The category extra for {@link #ACTION_CHANGE_DEFAULT} - * - * @see #ACTION_CHANGE_DEFAULT - */ - public static final String EXTRA_CATEGORY = "category"; - - /** - * The ComponentName object passed in as a parcelable - * extra for {@link #ACTION_CHANGE_DEFAULT} - * - * @see #ACTION_CHANGE_DEFAULT - */ - public static final String EXTRA_SERVICE_COMPONENT = "component"; - - /** - * The payment category can be used to indicate that an AID - * represents a payment application. - */ - public static final String CATEGORY_PAYMENT = "payment"; - - /** - * If an AID group does not contain a category, or the - * specified category is not defined by the platform version - * that is parsing the AID group, all AIDs in the group will - * automatically be categorized under the {@link #CATEGORY_OTHER} - * category. - */ - public static final String CATEGORY_OTHER = "other"; - - /** - * Return value for {@link #getSelectionModeForCategory(String)}. - * - * <p>In this mode, the user has set a default service for this - * AID category. If a remote reader selects any of the AIDs - * that the default service has registered in this category, - * that service will automatically be bound to to handle - * the transaction. - * - * <p>There are still cases where a service that is - * not the default for a category can selected: - * <p> - * If a remote reader selects an AID in this category - * that is not handled by the default service, and there is a set - * of other services {S} that do handle this AID, the - * user is asked if he wants to use any of the services in - * {S} instead. - * <p> - * As a special case, if the size of {S} is one, containing a single service X, - * and all AIDs X has registered in this category are not - * registered by any other service, then X will be - * selected automatically without asking the user. - * <p>Example: - * <ul> - * <li>Service A registers AIDs "1", "2" and "3" in the category - * <li>Service B registers AIDs "3" and "4" in the category - * <li>Service C registers AIDs "5" and "6" in the category - * </ul> - * In this case, the following will happen when service A - * is the default: - * <ul> - * <li>Reader selects AID "1", "2" or "3": service A is invoked automatically - * <li>Reader selects AID "4": the user is asked to confirm he - * wants to use service B, because its AIDs overlap with service A. - * <li>Reader selects AID "5" or "6": service C is invoked automatically, - * because all AIDs it has asked for are only registered by C, - * and there is no overlap. - * </ul> - * - */ - public static final int SELECTION_MODE_PREFER_DEFAULT = 0; - - /** - * Return value for {@link #getSelectionModeForCategory(String)}. - * - * <p>In this mode, whenever an AID of this category is selected, - * the user is asked which service he wants to use to handle - * the transaction, even if there is only one matching service. - */ - public static final int SELECTION_MODE_ALWAYS_ASK = 1; - - /** - * Return value for {@link #getSelectionModeForCategory(String)}. - * - * <p>In this mode, the user will only be asked to select a service - * if the selected AID has been registered by multiple applications. - */ - public static final int SELECTION_MODE_ASK_IF_CONFLICT = 2; - - static boolean sIsInitialized = false; - static HashMap<Context, CardEmulationManager> sCardEmuManagers = new HashMap(); - static INfcCardEmulation sService; - - final Context mContext; - - private CardEmulationManager(Context context, INfcCardEmulation service) { - mContext = context.getApplicationContext(); - sService = service; - } - - public static synchronized CardEmulationManager getInstance(NfcAdapter adapter) { - if (adapter == null) throw new NullPointerException("NfcAdapter is null"); - Context context = adapter.getContext(); - if (context == null) { - Log.e(TAG, "NfcAdapter context is null."); - throw new UnsupportedOperationException(); - } - if (!sIsInitialized) { - IPackageManager pm = ActivityThread.getPackageManager(); - if (pm == null) { - Log.e(TAG, "Cannot get PackageManager"); - throw new UnsupportedOperationException(); - } - try { - if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)) { - Log.e(TAG, "This device does not support card emulation"); - throw new UnsupportedOperationException(); - } - } catch (RemoteException e) { - Log.e(TAG, "PackageManager query failed."); - throw new UnsupportedOperationException(); - } - sIsInitialized = true; - } - CardEmulationManager manager = sCardEmuManagers.get(context); - if (manager == null) { - // Get card emu service - INfcCardEmulation service = adapter.getCardEmulationService(); - manager = new CardEmulationManager(context, service); - sCardEmuManagers.put(context, manager); - } - return manager; - } - - /** - * Allows an application to query whether a service is currently - * the default service to handle a card emulation category. - * - * <p>Note that if {@link #getSelectionModeForCategory(String)} - * returns {@link #SELECTION_MODE_ALWAYS_ASK}, this method will always - * return false. - * - * @param service The ComponentName of the service - * @param category The category - * @return whether service is currently the default service for the category. - */ - public boolean isDefaultServiceForCategory(ComponentName service, String category) { - try { - return sService.isDefaultServiceForCategory(UserHandle.myUserId(), service, category); - } catch (RemoteException e) { - // Try one more time - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return false; - } - try { - return sService.isDefaultServiceForCategory(UserHandle.myUserId(), service, - category); - } catch (RemoteException ee) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return false; - } - } - } - - /** - * - * Allows an application to query whether a service is currently - * the default handler for a specified ISO7816-4 Application ID. - * - * @param service The ComponentName of the service - * @param aid The ISO7816-4 Application ID - * @return - */ - public boolean isDefaultServiceForAid(ComponentName service, String aid) { - try { - return sService.isDefaultServiceForAid(UserHandle.myUserId(), service, aid); - } catch (RemoteException e) { - // Try one more time - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return false; - } - try { - return sService.isDefaultServiceForAid(UserHandle.myUserId(), service, aid); - } catch (RemoteException ee) { - Log.e(TAG, "Failed to reach CardEmulationService."); - return false; - } - } - } - - /** - * Returns the application selection mode for the passed in category. - * Valid return values are: - * <p>{@link #SELECTION_MODE_PREFER_DEFAULT} the user has requested a default - * application for this category, which will be preferred. - * <p>{@link #SELECTION_MODE_ALWAYS_ASK} the user has requested to be asked - * every time what app he would like to use in this category. - * <p>{@link #SELECTION_MODE_ASK_IF_CONFLICT} the user will only be asked - * to pick a service if there is a conflict. - * @param category The category, for example {@link #CATEGORY_PAYMENT} - * @return - */ - public int getSelectionModeForCategory(String category) { - if (CATEGORY_PAYMENT.equals(category)) { - String defaultComponent = Settings.Secure.getString(mContext.getContentResolver(), - Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT); - if (defaultComponent != null) { - return SELECTION_MODE_PREFER_DEFAULT; - } else { - return SELECTION_MODE_ALWAYS_ASK; - } - } else { - // All other categories are in "only ask if conflict" mode - return SELECTION_MODE_ASK_IF_CONFLICT; - } - } - - /** - * @hide - */ - public boolean setDefaultServiceForCategory(ComponentName service, String category) { - try { - return sService.setDefaultServiceForCategory(UserHandle.myUserId(), service, category); - } catch (RemoteException e) { - // Try one more time - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return false; - } - try { - return sService.setDefaultServiceForCategory(UserHandle.myUserId(), service, - category); - } catch (RemoteException ee) { - Log.e(TAG, "Failed to reach CardEmulationService."); - return false; - } - } - } - - /** - * @hide - */ - public boolean setDefaultForNextTap(ComponentName service) { - try { - return sService.setDefaultForNextTap(UserHandle.myUserId(), service); - } catch (RemoteException e) { - // Try one more time - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return false; - } - try { - return sService.setDefaultForNextTap(UserHandle.myUserId(), service); - } catch (RemoteException ee) { - Log.e(TAG, "Failed to reach CardEmulationService."); - return false; - } - } - } - /** - * @hide - */ - public List<ApduServiceInfo> getServices(String category) { - try { - return sService.getServices(UserHandle.myUserId(), category); - } catch (RemoteException e) { - // Try one more time - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return null; - } - try { - return sService.getServices(UserHandle.myUserId(), category); - } catch (RemoteException ee) { - Log.e(TAG, "Failed to reach CardEmulationService."); - return null; - } - } - } - - void recoverService() { - NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext); - sService = adapter.getCardEmulationService(); - } -} diff --git a/core/java/android/nfc/cardemulation/HostApduService.java b/core/java/android/nfc/cardemulation/HostApduService.java index 174acc0..e2c3ca6 100644 --- a/core/java/android/nfc/cardemulation/HostApduService.java +++ b/core/java/android/nfc/cardemulation/HostApduService.java @@ -50,23 +50,6 @@ public abstract class HostApduService extends Service { "android.nfc.cardemulation.host_apdu_service"; /** - * The {@link Intent} that must be declared as handled by the service. - * TODO Remove - * @hide - */ - public static final String OLD_SERVICE_INTERFACE = - "android.nfc.HostApduService"; - - /** - * The name of the meta-data element that contains - * more information about this service. - * - * TODO Remove - * @hide - */ - public static final String OLD_SERVICE_META_DATA = "android.nfc.HostApduService"; - - /** * Reason for {@link #onDeactivated(int)}. * Indicates deactivation was due to the NFC link * being lost. @@ -282,37 +265,7 @@ public abstract class HostApduService extends Service { * @return a byte-array containing the response APDU, or null if no * response APDU can be sent at this point. */ - public byte[] processCommandApdu(byte[] commandApdu, Bundle extras) { - // TODO make this abstract - return processCommandApdu(commandApdu, 0); - } - - /** - * <p>This method will be called when a command APDU has been received - * from a remote device. A response APDU can be provided directly - * by returning a byte-array in this method. Note that in general - * response APDUs must be sent as quickly as possible, given the fact - * that the user is likely holding his device over an NFC reader - * when this method is called. - * - * <p class="note">If there are multiple services that have registered for the same - * AIDs in their meta-data entry, you will only get called if the user has - * explicitly selected your service, either as a default or just for the next tap. - * - * <p class="note">This method is running on the main thread of your application. - * If you cannot return a response APDU immediately, return null - * and use the {@link #sendResponseApdu(byte[])} method later. - * - * @deprecated use {@link #processCommandApdu(byte[], Bundle)} - * @param commandApdu - * @param flags - * @return a byte-array containing the response APDU, or null if no - * response APDU can be sent at this point. - * @hide - */ - public byte[] processCommandApdu(byte[] commandApdu, int flags) { - return null; - } + public abstract byte[] processCommandApdu(byte[] commandApdu, Bundle extras); /** * This method will be called in two possible scenarios: diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index 52e5f38..5e0d489 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -407,7 +407,7 @@ public final class PowerManager { */ public WakeLock newWakeLock(int levelAndFlags, String tag) { validateWakeLockParameters(levelAndFlags, tag); - return new WakeLock(levelAndFlags, tag, mContext.getBasePackageName()); + return new WakeLock(levelAndFlags, tag, mContext.getOpPackageName()); } /** @hide */ diff --git a/core/java/android/os/SystemVibrator.java b/core/java/android/os/SystemVibrator.java index e66fb28..700f80d 100644 --- a/core/java/android/os/SystemVibrator.java +++ b/core/java/android/os/SystemVibrator.java @@ -39,7 +39,7 @@ public class SystemVibrator extends Vibrator { } public SystemVibrator(Context context) { - mPackageName = context.getBasePackageName(); + mPackageName = context.getOpPackageName(); mService = IVibratorService.Stub.asInterface( ServiceManager.getService("vibrator")); } diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java index 9d52c83..a6f23a8 100644 --- a/core/java/android/provider/CallLog.java +++ b/core/java/android/provider/CallLog.java @@ -137,8 +137,18 @@ public class CallLog { public static final String NUMBER = "number"; /** - * The number presenting rules set by the network for "allowed", - * "payphone", "restricted" or "unknown". + * The number presenting rules set by the network. + * + * <p> + * Allowed values: + * <ul> + * <li>{@link #PRESENTATION_ALLOWED}</li> + * <li>{@link #PRESENTATION_RESTRICTED}</li> + * <li>{@link #PRESENTATION_UNKNOWN}</li> + * <li>{@link #PRESENTATION_PAYPHONE}</li> + * </ul> + * </p> + * * <P>Type: INTEGER</P> */ public static final String NUMBER_PRESENTATION = "presentation"; diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 1a80818..025926e 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -2439,7 +2439,9 @@ public final class Settings { SIP_CALL_OPTIONS, SIP_RECEIVE_CALLS, POINTER_SPEED, - VIBRATE_WHEN_RINGING + VIBRATE_WHEN_RINGING, + RINGTONE, + NOTIFICATION_SOUND }; // Settings moved to Settings.Secure @@ -3333,7 +3335,9 @@ public final class Settings { */ public static final int LOCATION_MODE_SENSORS_ONLY = 1; /** - * Reduced power usage, such as limiting the number of GPS updates per hour. + * Reduced power usage, such as limiting the number of GPS updates per hour. Requests + * with {@link android.location.Criteria#POWER_HIGH} may be downgraded to + * {@link android.location.Criteria#POWER_MEDIUM}. */ public static final int LOCATION_MODE_BATTERY_SAVING = 2; /** @@ -4382,10 +4386,13 @@ public final class Settings { /** * Helper method for determining if a location provider is enabled. + * * @param cr the content resolver to use * @param provider the location provider to query * @return true if the provider is enabled - * @deprecated use {@link #getInt(ContentResolver, String)} and {@link #LOCATION_MODE} + * + * @deprecated use {@link #LOCATION_MODE} or + * {@link LocationManager#isProviderEnabled(String)} */ @Deprecated public static final boolean isLocationProviderEnabled(ContentResolver cr, String provider) { @@ -4398,8 +4405,8 @@ public final class Settings { * @param provider the location provider to query * @param userId the userId to query * @return true if the provider is enabled - * @deprecated use {@link #getIntForUser(ContentResolver, String, int, int)} and - * {@link #LOCATION_MODE} + * @deprecated use {@link #LOCATION_MODE} or + * {@link LocationManager#isProviderEnabled(String)} * @hide */ @Deprecated diff --git a/core/java/android/speech/RecognizerIntent.java b/core/java/android/speech/RecognizerIntent.java index 457e66c..e991d84 100644 --- a/core/java/android/speech/RecognizerIntent.java +++ b/core/java/android/speech/RecognizerIntent.java @@ -55,7 +55,10 @@ public class RecognizerIntent { * <p>Starting this intent with just {@link Activity#startActivity(Intent)} is not supported. * You must either use {@link Activity#startActivityForResult(Intent, int)}, or provide a * PendingIntent, to receive recognition results. - * + * + * <p>The implementation of this API is likely to stream audio to remote servers to perform + * speech recognition which can use a substantial amount of bandwidth. + * * <p>Required extras: * <ul> * <li>{@link #EXTRA_LANGUAGE_MODEL} diff --git a/core/java/android/speech/SpeechRecognizer.java b/core/java/android/speech/SpeechRecognizer.java index 8fee41d..94aedbd 100644 --- a/core/java/android/speech/SpeechRecognizer.java +++ b/core/java/android/speech/SpeechRecognizer.java @@ -39,8 +39,14 @@ import java.util.Queue; * This class provides access to the speech recognition service. This service allows access to the * speech recognizer. Do not instantiate this class directly, instead, call * {@link SpeechRecognizer#createSpeechRecognizer(Context)}. This class's methods must be - * invoked only from the main application thread. Please note that the application must have - * {@link android.Manifest.permission#RECORD_AUDIO} permission to use this class. + * invoked only from the main application thread. + * + * <p>The implementation of this API is likely to stream audio to remote servers to perform speech + * recognition. As such this API is not intended to be used for continuous recognition, which would + * consume a significant amount of battery and bandwidth. + * + * <p>Please note that the application must have {@link android.Manifest.permission#RECORD_AUDIO} + * permission to use this class. */ public class SpeechRecognizer { /** DEBUG value to enable verbose debug prints */ diff --git a/core/java/android/speech/hotword/HotwordRecognitionListener.java b/core/java/android/speech/hotword/HotwordRecognitionListener.java deleted file mode 100644 index 8a32654..0000000 --- a/core/java/android/speech/hotword/HotwordRecognitionListener.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2013 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.speech.hotword; - -import android.content.Intent; -import android.os.Bundle; - -/** - * Used for receiving notifications from the HotwordRecognitionService when the - * hotword recognition related events occur. - * All the callbacks are executed on the application main thread. - * {@hide} - */ -public interface HotwordRecognitionListener { - /** - * Called when the service starts listening for hotword. - */ - void onHotwordRecognitionStarted(); - - /** - * Called when the service stops listening for hotword. - */ - void onHotwordRecognitionStopped(); - - /** - * Called on an event of interest to the client. - * - * @param eventType the event type. - * @param eventBundle a Bundle containing the hotword event(s). - */ - void onHotwordEvent(int eventType, Bundle eventBundle); - - /** - * Called back when hotword is detected. - * - * @param intent for the activity to launch, post hotword detection. - */ - void onHotwordRecognized(Intent intent); - - /** - * Called when the HotwordRecognitionService encounters an error. - * - * @param errorCode the error code describing the error that was encountered. - */ - void onHotwordError(int errorCode); -}
\ No newline at end of file diff --git a/core/java/android/speech/hotword/HotwordRecognitionService.java b/core/java/android/speech/hotword/HotwordRecognitionService.java deleted file mode 100644 index 1cba281..0000000 --- a/core/java/android/speech/hotword/HotwordRecognitionService.java +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright (C) 2013 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.speech.hotword; - -import android.annotation.SdkConstant; -import android.annotation.SdkConstant.SdkConstantType; -import android.app.PendingIntent; -import android.app.Service; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.os.Bundle; -import android.os.Handler; -import android.os.IBinder; -import android.os.Message; -import android.os.RemoteException; -import android.util.Log; - -/** - * This class provides a base class for hotword detection service implementations. - * This class should be extended only if you wish to implement a new hotword recognizer. - */ -public abstract class HotwordRecognitionService extends Service { - /** - * The {@link Intent} that must be declared as handled by the service. - */ - @SdkConstant(SdkConstantType.SERVICE_ACTION) - public static final String SERVICE_INTERFACE = - "android.speech.hotword.HotwordRecognitionService"; - - /** Log messages identifier */ - private static final String TAG = "HotwordRecognitionService"; - - /** Debugging flag */ - private static final boolean DBG = false; - - /** - * Key used to retrieve a string to be displayed to the user. - */ - public static final String KEY_PROMPT_TEXT = "prompt_text"; - - /** - * Event type used to indicate to the user that the prompt for - * hotword recognition has changed. - */ - public static final int EVENT_TYPE_PROMPT_CHANGED = 1; - - /** Audio recording error. */ - public static final int ERROR_AUDIO = 1; - - /** RecognitionService busy. */ - public static final int ERROR_RECOGNIZER_BUSY = 2; - - /** This indicates a permanent failure and the clients shouldn't retry on this */ - public static final int ERROR_FAILED = 3; - - /** Client-side errors */ - public static final int ERROR_CLIENT = 4; - - /** The service timed out */ - public static final int ERROR_TIMEOUT = 5; - - /** The service received concurrent start calls */ - public static final int ERROR_SERVICE_ALREADY_STARTED = 6; - - /** Hotword recognition is unavailable on the device */ - public static final int ERROR_UNAVAILABLE = 7; - - private static final int MSG_START_RECOGNITION = 1; - private static final int MSG_STOP_RECOGNITION = 2; - - /** - * The current callback of an application that invoked the - * {@link HotwordRecognitionService#onStartHotwordRecognition(Callback)} method - */ - private Callback mCurrentCallback = null; - - // Handle the client dying. - private final IBinder.DeathRecipient mCallbackDeathRecipient = new IBinder.DeathRecipient() { - @Override - public void binderDied() { - if (DBG) Log.i(TAG, "HotwordRecognitionService listener died"); - mCurrentCallback = null; - } - }; - - private final Handler mHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case MSG_START_RECOGNITION: - dispatchStartRecognition((IHotwordRecognitionListener) msg.obj); - break; - case MSG_STOP_RECOGNITION: - dispatchStopRecognition((IHotwordRecognitionListener) msg.obj); - break; - } - } - }; - - /** Binder of the hotword recognition service */ - private RecognitionServiceBinder mBinder = new RecognitionServiceBinder(this); - - private void dispatchStartRecognition(IHotwordRecognitionListener listener) { - if (mCurrentCallback == null) { - if (DBG) Log.d(TAG, "created new mCurrentCallback, listener = " + listener.asBinder()); - try { - listener.asBinder().linkToDeath(mCallbackDeathRecipient, 0); - } catch (RemoteException e) { - if (DBG) Log.d(TAG, "listener died before linkToDeath()"); - } - mCurrentCallback = new Callback(listener); - HotwordRecognitionService.this.onStartHotwordRecognition(mCurrentCallback); - } else { - try { - listener.onHotwordError(ERROR_RECOGNIZER_BUSY); - } catch (RemoteException e) { - if (DBG) Log.d(TAG, "onError call from startRecognition failed"); - } - if (DBG) Log.d(TAG, "concurrent startRecognition received - ignoring this call"); - } - } - - private void dispatchStopRecognition(IHotwordRecognitionListener listener) { - try { - if (mCurrentCallback == null) { - listener.onHotwordError(ERROR_CLIENT); - Log.w(TAG, "stopRecognition called with no preceding startRecognition - ignoring"); - } else if (mCurrentCallback.mListener.asBinder() != listener.asBinder()) { - listener.onHotwordError(ERROR_RECOGNIZER_BUSY); - Log.w(TAG, "stopRecognition called by a different caller - ignoring"); - } else { // the correct state - mCurrentCallback.onHotwordRecognitionStopped(); - mCurrentCallback = null; - HotwordRecognitionService.this.onStopHotwordRecognition(); - } - } catch (RemoteException e) { // occurs if onError fails - if (DBG) Log.d(TAG, "onError call from stopRecognition failed"); - } - } - - @Override - public IBinder onBind(final Intent intent) { - if (DBG) Log.d(TAG, "onBind, intent=" + intent); - return mBinder; - } - - @Override - public void onDestroy() { - if (DBG) Log.d(TAG, "onDestroy"); - if (mCurrentCallback != null) { - mCurrentCallback.mListener.asBinder().unlinkToDeath(mCallbackDeathRecipient, 0); - mCurrentCallback = null; - } - mBinder.clearReference(); - super.onDestroy(); - } - - /** - * Notifies the service to start a recognition. - * - * @param callback that receives the callbacks from the service. - */ - public abstract void onStartHotwordRecognition(Callback callback); - - /** - * Notifies the service to stop recognition. - */ - public abstract void onStopHotwordRecognition(); - - /** Binder of the hotword recognition service */ - private static class RecognitionServiceBinder extends IHotwordRecognitionService.Stub { - private HotwordRecognitionService mInternalService; - - public RecognitionServiceBinder(HotwordRecognitionService service) { - mInternalService = service; - } - - public void startHotwordRecognition(IHotwordRecognitionListener listener) { - if (DBG) Log.d(TAG, "startRecognition called by: " + listener.asBinder()); - if (mInternalService != null && mInternalService.checkPermissions(listener)) { - mInternalService.mHandler.sendMessage( - Message.obtain(mInternalService.mHandler, MSG_START_RECOGNITION, listener)); - } - } - - public void stopHotwordRecognition(IHotwordRecognitionListener listener) { - if (DBG) Log.d(TAG, "stopRecognition called by: " + listener.asBinder()); - if (mInternalService != null && mInternalService.checkPermissions(listener)) { - mInternalService.mHandler.sendMessage( - Message.obtain(mInternalService.mHandler, MSG_STOP_RECOGNITION, listener)); - } - } - - private void clearReference() { - mInternalService = null; - } - } - - /** - * Checks whether the caller has sufficient permissions - * - * @param listener to send the error message to in case of error. - * @return {@code true} if the caller has enough permissions, {@code false} otherwise. - */ - private boolean checkPermissions(IHotwordRecognitionListener listener) { - if (DBG) Log.d(TAG, "checkPermissions"); - if (checkCallingOrSelfPermission(android.Manifest.permission.HOTWORD_RECOGNITION) == - PackageManager.PERMISSION_GRANTED) { - return true; - } - try { - Log.e(TAG, "Recognition service called without HOTWORD_RECOGNITION permissions"); - listener.onHotwordError(ERROR_FAILED); - } catch (RemoteException e) { - Log.e(TAG, "onHotwordError(ERROR_FAILED) message failed", e); - } - return false; - } - - /** - * This class acts passes on the callbacks received from the Hotword service - * to the listener. - */ - public static class Callback { - private final IHotwordRecognitionListener mListener; - - private Callback(IHotwordRecognitionListener listener) { - mListener = listener; - } - - /** - * Called when the service starts listening for hotword. - */ - public void onHotwordRecognitionStarted() throws RemoteException { - mListener.onHotwordRecognitionStarted(); - } - - /** - * Called when the service starts listening for hotword. - */ - public void onHotwordRecognitionStopped() throws RemoteException { - mListener.onHotwordRecognitionStopped(); - } - - /** - * Called on an event of interest to the client. - * - * @param eventType the event type. - * @param eventBundle a Bundle containing the hotword event(s). - */ - public void onHotwordEvent(int eventType, Bundle eventBundle) throws RemoteException { - mListener.onHotwordEvent(eventType, eventBundle); - } - - /** - * Called back when hotword is detected. - * - * @param activityIntent for the activity to launch, post hotword detection. - */ - public void onHotwordRecognized(Intent activityIntent) throws RemoteException { - mListener.onHotwordRecognized(activityIntent); - } - - /** - * Called when the HotwordRecognitionService encounters an error. - * - * @param errorCode the error code describing the error that was encountered. - */ - public void onError(int errorCode) throws RemoteException { - mListener.onHotwordError(errorCode); - } - } -} diff --git a/core/java/android/speech/hotword/HotwordRecognizer.java b/core/java/android/speech/hotword/HotwordRecognizer.java deleted file mode 100644 index 9f05f31..0000000 --- a/core/java/android/speech/hotword/HotwordRecognizer.java +++ /dev/null @@ -1,362 +0,0 @@ -/* - * Copyright (C) 2013 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.speech.hotword; - -import android.app.PendingIntent; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.os.Bundle; -import android.os.Handler; -import android.os.IBinder; -import android.os.Looper; -import android.os.Message; -import android.os.RemoteException; -import android.provider.Settings; -import android.text.TextUtils; -import android.util.Log; - -import java.util.LinkedList; -import java.util.List; -import java.util.Queue; - -/** - * This class provides access to the Hotword recognition service. - * This class's methods must be invoked on the main application thread. - * {@hide} - */ -public class HotwordRecognizer { - /** DEBUG value to enable verbose debug prints */ - private final static boolean DBG = false; - - /** Log messages identifier */ - private static final String TAG = "HotwordRecognizer"; - - /** action codes */ - private static final int MSG_START = 1; - private static final int MSG_STOP = 2; - - /** The underlying HotwordRecognitionService endpoint */ - private IHotwordRecognitionService mService; - - /** The connection to the actual service */ - private Connection mConnection; - - /** Context with which the manager was created */ - private final Context mContext; - - /** Component to direct service intent to */ - private final ComponentName mServiceComponent; - - /** Handler that will execute the main tasks */ - private Handler mHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case MSG_START: - handleStartRecognition(); - break; - case MSG_STOP: - handleStopRecognition(); - break; - } - } - }; - - /** - * Temporary queue, saving the messages until the connection will be established, afterwards, - * only mHandler will receive the messages - */ - private final Queue<Message> mPendingTasks = new LinkedList<Message>(); - - /** The Listener that will receive all the callbacks */ - private final InternalListener mListener = new InternalListener(); - - /** - * Checks whether a hotword recognition service is available on the system. If this method - * returns {@code false}, {@link HotwordRecognizer#createHotwordRecognizer(Context)} will - * fail. - * - * @param context with which {@code HotwordRecognizer} will be created - * @return {@code true} if recognition is available, {@code false} otherwise - */ - public static boolean isHotwordRecognitionAvailable(final Context context) { - final List<ResolveInfo> list = context.getPackageManager().queryIntentServices( - new Intent(HotwordRecognitionService.SERVICE_INTERFACE), 0); - return list != null && list.size() != 0; - } - - /** - * Factory method to create a new {@code HotwordRecognizer}. - * - * @param context in which to create {@code HotwordRecognizer} - * @return a new {@code HotwordRecognizer} - */ - public static HotwordRecognizer createHotwordRecognizer(final Context context) { - ComponentName serviceComponent = null; - // Resolve to a default ComponentName. - final List<ResolveInfo> list = context.getPackageManager().queryIntentServices( - new Intent(HotwordRecognitionService.SERVICE_INTERFACE), 0); - for (int i = 0; i < list.size(); i++) { - final ResolveInfo ri = list.get(i); - if (!ri.serviceInfo.enabled) { - continue; - } - if ((ri.serviceInfo.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) - != PackageManager.MATCH_DEFAULT_ONLY) { - serviceComponent = new ComponentName( - ri.serviceInfo.packageName, ri.serviceInfo.name); - break; - } - } - // If all else fails, pick the first one. - if (serviceComponent == null && !list.isEmpty()) { - serviceComponent = new ComponentName( - list.get(0).serviceInfo.packageName, list.get(0).serviceInfo.name); - } - return createHotwordRecognizer(context, serviceComponent); - } - - /** - * Factory method to create a new {@code HotwordRecognizer}. - * - * Use this version of the method to specify a specific service to direct this - * {@link HotwordRecognizer} to. Normally you would not use this; use - * {@link #createHotwordRecognizer(Context)} instead to use the system default recognition - * service. - * - * @param context in which to create {@code HotwordRecognizer} - * @param serviceComponent the {@link ComponentName} of a specific service to direct this - * {@code HotwordRecognizer} to - * @return a new {@code HotwordRecognizer} - */ - public static HotwordRecognizer createHotwordRecognizer( - final Context context, final ComponentName serviceComponent) { - if (context == null) { - throw new IllegalArgumentException("Context cannot be null)"); - } - checkIsCalledFromMainThread(); - return new HotwordRecognizer(context, serviceComponent); - } - - /** - * Starts recognizing hotword and sets the listener that will receive the callbacks. - * - * @param listener listener that will receive all the callbacks from the created - * {@link HotwordRecognizer}, this must not be null. - */ - public void startRecognition(HotwordRecognitionListener listener) { - checkIsCalledFromMainThread(); - if (mConnection == null) { // first time connection - if (listener == null) { - throw new IllegalArgumentException("listener must not be null"); - } - - mConnection = new Connection(); - Intent serviceIntent = new Intent(HotwordRecognitionService.SERVICE_INTERFACE); - mListener.mInternalListener = listener; - - if (mServiceComponent == null) { - Log.e(TAG, "no selected voice recognition service"); - mListener.onHotwordError(HotwordRecognitionService.ERROR_CLIENT); - return; - } else { - serviceIntent.setComponent(mServiceComponent); - } - - if (!mContext.bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE)) { - Log.e(TAG, "bind to recognition service failed"); - mConnection = null; - mService = null; - mListener.onHotwordError(HotwordRecognitionService.ERROR_CLIENT); - return; - } - putMessage(Message.obtain(mHandler, MSG_START)); - } else { - mListener.onHotwordError(HotwordRecognitionService.ERROR_SERVICE_ALREADY_STARTED); - return; - } - } - - /** - * Stops recognizing hotword. - */ - public void stopRecognition() { - checkIsCalledFromMainThread(); - putMessage(Message.obtain(mHandler, MSG_STOP)); - } - - // Private constructor. - private HotwordRecognizer(Context context, ComponentName serviceComponent) { - mContext = context; - mServiceComponent = serviceComponent; - } - - private void handleStartRecognition() { - if (!checkOpenConnection()) { - return; - } - try { - mService.startHotwordRecognition(mListener); - if (DBG) Log.d(TAG, "service startRecognition command succeeded"); - } catch (final RemoteException e) { - Log.e(TAG, "startRecognition() failed", e); - mListener.onHotwordError(HotwordRecognitionService.ERROR_CLIENT); - } - } - - private void handleStopRecognition() { - if (!checkOpenConnection()) { - return; - } - try { - mService.stopHotwordRecognition(mListener); - if (mConnection != null) { - mContext.unbindService(mConnection); - } - if (DBG) Log.d(TAG, "service stopRecognition command succeeded"); - } catch (final RemoteException e) { - Log.e(TAG, "stopRecognition() failed", e); - mListener.onHotwordError(HotwordRecognitionService.ERROR_CLIENT); - } finally { - mPendingTasks.clear(); - mService = null; - mConnection = null; - mListener.mInternalListener = null; - } - } - - private boolean checkOpenConnection() { - if (mService != null) { - return true; - } - mListener.onHotwordError(HotwordRecognitionService.ERROR_CLIENT); - Log.e(TAG, "not connected to the recognition service"); - return false; - } - - private static void checkIsCalledFromMainThread() { - if (Looper.myLooper() != Looper.getMainLooper()) { - throw new RuntimeException( - "HotwordRecognizer should be used only from the application's main thread"); - } - } - - private void putMessage(Message msg) { - if (mService == null) { - mPendingTasks.offer(msg); - } else { - mHandler.sendMessage(msg); - } - } - - /** - * Basic ServiceConnection that records the mService variable. - * Additionally, on creation it invokes - * {@link IHotwordRecognitionService#startHotwordRecognition(IHotwordRecognitionListener)}. - */ - private class Connection implements ServiceConnection { - - public void onServiceConnected(final ComponentName name, final IBinder service) { - // always done on the application main thread, so no need to send message to mHandler - mService = IHotwordRecognitionService.Stub.asInterface(service); - if (DBG) Log.d(TAG, "onServiceConnected - Success"); - while (!mPendingTasks.isEmpty()) { - mHandler.sendMessage(mPendingTasks.poll()); - } - } - - public void onServiceDisconnected(final ComponentName name) { - // always done on the application main thread, so no need to send message to mHandler - mService = null; - mConnection = null; - mPendingTasks.clear(); - if (DBG) Log.d(TAG, "onServiceDisconnected - Success"); - } - } - - /** - * Internal wrapper of IHotwordRecognitionListener which will propagate the results to - * HotwordRecognitionListener. - */ - private class InternalListener extends IHotwordRecognitionListener.Stub { - private HotwordRecognitionListener mInternalListener; - - private final static int MSG_ON_START = 1; - private final static int MSG_ON_STOP = 2; - private final static int MSG_ON_EVENT = 3; - private final static int MSG_ON_RECOGNIZED = 4; - private final static int MSG_ON_ERROR = 5; - - private final Handler mInternalHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - if (mInternalListener == null) { - return; - } - switch (msg.what) { - case MSG_ON_START: - mInternalListener.onHotwordRecognitionStarted(); - break; - case MSG_ON_STOP: - mInternalListener.onHotwordRecognitionStopped(); - break; - case MSG_ON_EVENT: - mInternalListener.onHotwordEvent(msg.arg1, (Bundle) msg.obj); - break; - case MSG_ON_RECOGNIZED: - mInternalListener.onHotwordRecognized((Intent) msg.obj); - break; - case MSG_ON_ERROR: - mInternalListener.onHotwordError((Integer) msg.obj); - break; - } - } - }; - - @Override - public void onHotwordRecognitionStarted() throws RemoteException { - Message.obtain(mInternalHandler, MSG_ON_START).sendToTarget(); - } - - @Override - public void onHotwordRecognitionStopped() throws RemoteException { - Message.obtain(mInternalHandler, MSG_ON_STOP).sendToTarget(); - } - - @Override - public void onHotwordEvent(final int eventType, final Bundle params) { - Message.obtain(mInternalHandler, MSG_ON_EVENT, eventType, eventType, params) - .sendToTarget(); - } - - @Override - public void onHotwordRecognized(Intent activityIntent) throws RemoteException { - Message.obtain(mInternalHandler, MSG_ON_RECOGNIZED, activityIntent) - .sendToTarget(); - } - - @Override - public void onHotwordError(final int error) { - Message.obtain(mInternalHandler, MSG_ON_ERROR, error).sendToTarget(); - } - } -} diff --git a/core/java/android/speech/hotword/IHotwordRecognitionListener.aidl b/core/java/android/speech/hotword/IHotwordRecognitionListener.aidl deleted file mode 100644 index 4ea2e8e..0000000 --- a/core/java/android/speech/hotword/IHotwordRecognitionListener.aidl +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2013 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.speech.hotword; - -import android.content.Intent; -import android.os.Bundle; - -/** - * Listener for hotword detection events. - * This indicates when the hotword was detected, and also notifies the - * client of the intermediate events that may be used to show visual feedback - * to the user. - * {@hide} - */ -oneway interface IHotwordRecognitionListener { - /** - * Called when the service starts listening for hotword. - */ - void onHotwordRecognitionStarted(); - - /** - * Called when the service starts listening for hotword. - */ - void onHotwordRecognitionStopped(); - - /** - * Called on an event of interest to the client. - * - * @param eventType the event type. - * @param eventBundle a Bundle containing the hotword event(s). - */ - void onHotwordEvent(in int eventType, in Bundle eventBundle); - - /** - * Called back when hotword is detected. - * - * @param intent for the activity to launch, post hotword detection. - */ - void onHotwordRecognized(in Intent intent); - - /** - * Called when the HotwordRecognitionService encounters an error. - * - * @param errorCode the error code describing the error that was encountered. - */ - void onHotwordError(in int errorCode); -} diff --git a/core/java/android/speech/hotword/IHotwordRecognitionService.aidl b/core/java/android/speech/hotword/IHotwordRecognitionService.aidl deleted file mode 100644 index 331d81c..0000000 --- a/core/java/android/speech/hotword/IHotwordRecognitionService.aidl +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2013 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.speech.hotword; - -import android.speech.hotword.IHotwordRecognitionListener; - -/** - * A service interface to Hotword recognition. - * Call startHotwordDetection with a listener when you want to begin detecting - * hotword; - * The service would automatically stop detection when hotword is detected; - * So it's a create-once use-once service. - * The service doesn't support nested calls to start detection and disallows them. - * {@hide} - */ -oneway interface IHotwordRecognitionService { - /** - * Start hotword recognition. - * The clients should rely on the callback to figure out if the detection was - * started. - * - * @param listener a listener to notify of hotword events. - */ - void startHotwordRecognition(in IHotwordRecognitionListener listener); - - /** - * Stop hotword recognition. - * Stops the recognition only if it was started by the same caller. - * - * @param listener a listener to notify of hotword events. - */ - void stopHotwordRecognition(in IHotwordRecognitionListener listener); -} diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java index 59df183..8ea9d48 100644 --- a/core/java/android/transition/Transition.java +++ b/core/java/android/transition/Transition.java @@ -122,6 +122,10 @@ public abstract class Transition implements Cloneable { // Whether this transition is currently paused, due to a call to pause() boolean mPaused = false; + // Whether this transition has ended. Used to avoid pause/resume on transitions + // that have completed + private boolean mEnded = false; + // The set of listeners to be sent transition lifecycle events. ArrayList<TransitionListener> mListeners = null; @@ -914,21 +918,23 @@ public abstract class Transition implements Cloneable { * @hide */ public void pause() { - ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators(); - int numOldAnims = runningAnimators.size(); - for (int i = numOldAnims - 1; i >= 0; i--) { - Animator anim = runningAnimators.keyAt(i); - anim.pause(); - } - if (mListeners != null && mListeners.size() > 0) { - ArrayList<TransitionListener> tmpListeners = - (ArrayList<TransitionListener>) mListeners.clone(); - int numListeners = tmpListeners.size(); - for (int i = 0; i < numListeners; ++i) { - tmpListeners.get(i).onTransitionPause(this); + if (!mEnded) { + ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators(); + int numOldAnims = runningAnimators.size(); + for (int i = numOldAnims - 1; i >= 0; i--) { + Animator anim = runningAnimators.keyAt(i); + anim.pause(); + } + if (mListeners != null && mListeners.size() > 0) { + ArrayList<TransitionListener> tmpListeners = + (ArrayList<TransitionListener>) mListeners.clone(); + int numListeners = tmpListeners.size(); + for (int i = 0; i < numListeners; ++i) { + tmpListeners.get(i).onTransitionPause(this); + } } + mPaused = true; } - mPaused = true; } /** @@ -940,18 +946,20 @@ public abstract class Transition implements Cloneable { */ public void resume() { if (mPaused) { - ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators(); - int numOldAnims = runningAnimators.size(); - for (int i = numOldAnims - 1; i >= 0; i--) { - Animator anim = runningAnimators.keyAt(i); - anim.resume(); - } - if (mListeners != null && mListeners.size() > 0) { - ArrayList<TransitionListener> tmpListeners = - (ArrayList<TransitionListener>) mListeners.clone(); - int numListeners = tmpListeners.size(); - for (int i = 0; i < numListeners; ++i) { - tmpListeners.get(i).onTransitionResume(this); + if (!mEnded) { + ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators(); + int numOldAnims = runningAnimators.size(); + for (int i = numOldAnims - 1; i >= 0; i--) { + Animator anim = runningAnimators.keyAt(i); + anim.resume(); + } + if (mListeners != null && mListeners.size() > 0) { + ArrayList<TransitionListener> tmpListeners = + (ArrayList<TransitionListener>) mListeners.clone(); + int numListeners = tmpListeners.size(); + for (int i = 0; i < numListeners; ++i) { + tmpListeners.get(i).onTransitionResume(this); + } } } mPaused = false; @@ -1071,6 +1079,7 @@ public abstract class Transition implements Cloneable { tmpListeners.get(i).onTransitionStart(this); } } + mEnded = false; } mNumInstances++; } @@ -1111,6 +1120,7 @@ public abstract class Transition implements Cloneable { v.setHasTransientState(false); } } + mEnded = true; } } diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java index ba64f6b..f215189 100644 --- a/core/java/android/view/HardwareRenderer.java +++ b/core/java/android/view/HardwareRenderer.java @@ -34,6 +34,8 @@ import android.os.SystemProperties; import android.os.Trace; import android.util.DisplayMetrics; import android.util.Log; +import android.view.Surface.OutOfResourcesException; + import com.google.android.gles_jni.EGLImpl; import javax.microedition.khronos.egl.EGL10; @@ -74,7 +76,7 @@ public abstract class HardwareRenderer { * System property used to enable or disable dirty regions invalidation. * This property is only queried if {@link #RENDER_DIRTY_REGIONS} is true. * The default value of this property is assumed to be true. - * + * * Possible values: * "true", to enable partial invalidates * "false", to disable partial invalidates @@ -134,7 +136,7 @@ public abstract class HardwareRenderer { /** * System property used to debug EGL configuration choice. - * + * * Possible values: * "choice", print the chosen configuration only * "all", print all possible configurations @@ -147,7 +149,7 @@ public abstract class HardwareRenderer { * Possible values: * "true", to enable dirty regions debugging * "false", to disable dirty regions debugging - * + * * @hide */ public static final String DEBUG_DIRTY_REGIONS_PROPERTY = "debug.hwui.show_dirty_regions"; @@ -208,14 +210,14 @@ public abstract class HardwareRenderer { /** * A process can set this flag to false to prevent the use of hardware * rendering. - * + * * @hide */ public static boolean sRendererDisabled = false; /** * Further hardware renderer disabling for the system process. - * + * * @hide */ public static boolean sSystemRendererDisabled = false; @@ -235,7 +237,7 @@ public abstract class HardwareRenderer { /** * Invoke this method to disable hardware rendering in the current process. - * + * * @hide */ public static void disable(boolean system) { @@ -248,7 +250,7 @@ public abstract class HardwareRenderer { /** * Indicates whether hardware acceleration is available under any form for * the view hierarchy. - * + * * @return True if the view hierarchy can potentially be hardware accelerated, * false otherwise */ @@ -258,30 +260,30 @@ public abstract class HardwareRenderer { /** * Destroys the hardware rendering context. - * + * * @param full If true, destroys all associated resources. */ abstract void destroy(boolean full); /** * Initializes the hardware renderer for the specified surface. - * + * * @param surface The surface to hardware accelerate - * + * * @return True if the initialization was successful, false otherwise. */ - abstract boolean initialize(Surface surface) throws Surface.OutOfResourcesException; - + abstract boolean initialize(Surface surface) throws OutOfResourcesException; + /** * Updates the hardware renderer for the specified surface. * * @param surface The surface to hardware accelerate */ - abstract void updateSurface(Surface surface) throws Surface.OutOfResourcesException; + abstract void updateSurface(Surface surface) throws OutOfResourcesException; /** * Destroys the layers used by the specified view hierarchy. - * + * * @param view The root of the view hierarchy */ abstract void destroyLayers(View view); @@ -289,11 +291,11 @@ public abstract class HardwareRenderer { /** * Destroys all hardware rendering resources associated with the specified * view hierarchy. - * + * * @param view The root of the view hierarchy */ abstract void destroyHardwareResources(View view); - + /** * This method should be invoked whenever the current hardware renderer * context should be reset. @@ -306,7 +308,7 @@ public abstract class HardwareRenderer { * This method should be invoked to ensure the hardware renderer is in * valid state (for instance, to ensure the correct EGL context is bound * to the current thread.) - * + * * @return true if the renderer is now valid, false otherwise */ abstract boolean validate(); @@ -314,7 +316,7 @@ public abstract class HardwareRenderer { /** * This method ensures the hardware renderer is in a valid state * before executing the specified action. - * + * * This method will attempt to set a valid state even if the window * the renderer is attached to was destroyed. * @@ -325,7 +327,7 @@ public abstract class HardwareRenderer { /** * Setup the hardware renderer for drawing. This is called whenever the * size of the target surface changes or when the surface is first created. - * + * * @param width Width of the drawing surface. * @param height Height of the drawing surface. */ @@ -384,7 +386,7 @@ public abstract class HardwareRenderer { /** * Sets the directory to use as a persistent storage for hardware rendering * resources. - * + * * @param cacheDir A directory the current process can write to * * @hide @@ -447,7 +449,7 @@ public abstract class HardwareRenderer { /** * Indicates that the specified hardware layer needs to be updated * as soon as possible. - * + * * @param layer The hardware layer that needs an update * * @see #flushLayerUpdates() @@ -481,7 +483,7 @@ public abstract class HardwareRenderer { * Invoked before a view is drawn by a hardware renderer. * This method can be used to apply transformations to the * canvas but no drawing command should be issued. - * + * * @param canvas The Canvas used to render the view. */ void onHardwarePreDraw(HardwareCanvas canvas); @@ -489,7 +491,7 @@ public abstract class HardwareRenderer { /** * Invoked after a view is drawn by a hardware renderer. * It is safe to invoke drawing commands from this method. - * + * * @param canvas The Canvas used to render the view. */ void onHardwarePostDraw(HardwareCanvas canvas); @@ -509,9 +511,9 @@ public abstract class HardwareRenderer { /** * Creates a new display list that can be used to record batches of * drawing operations. - * + * * @param name The name of the display list, used for debugging purpose. May be null. - * + * * @return A new display list. * * @hide @@ -521,20 +523,20 @@ public abstract class HardwareRenderer { /** * Creates a new hardware layer. A hardware layer built by calling this * method will be treated as a texture layer, instead of as a render target. - * + * * @param isOpaque Whether the layer should be opaque or not - * + * * @return A hardware layer */ abstract HardwareLayer createHardwareLayer(boolean isOpaque); /** * Creates a new hardware layer. - * + * * @param width The minimum width of the layer * @param height The minimum height of the layer * @param isOpaque Whether the layer should be opaque or not - * + * * @return A hardware layer */ abstract HardwareLayer createHardwareLayer(int width, int height, boolean isOpaque); @@ -544,7 +546,7 @@ public abstract class HardwareRenderer { * specified hardware layer. * * @param layer The layer to render into using a {@link android.graphics.SurfaceTexture} - * + * * @return A {@link SurfaceTexture} */ abstract SurfaceTexture createSurfaceTexture(HardwareLayer layer); @@ -560,11 +562,11 @@ public abstract class HardwareRenderer { /** * Detaches the specified functor from the current functor execution queue. - * + * * @param functor The native functor to remove from the execution queue. - * - * @see HardwareCanvas#callDrawGLFunction(int) - * @see #attachFunctor(android.view.View.AttachInfo, int) + * + * @see HardwareCanvas#callDrawGLFunction(int) + * @see #attachFunctor(android.view.View.AttachInfo, int) */ abstract void detachFunctor(int functor); @@ -591,12 +593,12 @@ public abstract class HardwareRenderer { * @param width The width of the drawing surface. * @param height The height of the drawing surface. * @param surface The surface to hardware accelerate - * + * * @return true if the surface was initialized, false otherwise. Returning * false might mean that the surface was already initialized. */ boolean initializeIfNeeded(int width, int height, Surface surface) - throws Surface.OutOfResourcesException { + throws OutOfResourcesException { if (isRequested()) { // We lost the gl context, so recreate it. if (!isEnabled()) { @@ -618,10 +620,10 @@ public abstract class HardwareRenderer { /** * Creates a hardware renderer using OpenGL. - * + * * @param glVersion The version of OpenGL to use (1 for OpenGL 1, 11 for OpenGL 1.1, etc.) * @param translucent True if the surface is translucent, false otherwise - * + * * @return A hardware renderer backed by OpenGL. */ static HardwareRenderer createGlRenderer(int glVersion, boolean translucent) { @@ -636,7 +638,7 @@ public abstract class HardwareRenderer { * Invoke this method when the system is running out of memory. This * method will attempt to recover as much memory as possible, based on * the specified hint. - * + * * @param level Hint about the amount of memory that should be trimmed, * see {@link android.content.ComponentCallbacks} */ @@ -649,7 +651,7 @@ public abstract class HardwareRenderer { * Starts the process of trimming memory. Usually this call will setup * hardware rendering context and reclaim memory.Extra cleanup might * be required by calling {@link #endTrimMemory()}. - * + * * @param level Hint about the amount of memory that should be trimmed, * see {@link android.content.ComponentCallbacks} */ @@ -667,7 +669,7 @@ public abstract class HardwareRenderer { /** * Indicates whether hardware acceleration is currently enabled. - * + * * @return True if hardware acceleration is in use, false otherwise. */ boolean isEnabled() { @@ -676,7 +678,7 @@ public abstract class HardwareRenderer { /** * Indicates whether hardware acceleration is currently enabled. - * + * * @param enabled True if the hardware renderer is in use, false otherwise. */ void setEnabled(boolean enabled) { @@ -686,7 +688,7 @@ public abstract class HardwareRenderer { /** * Indicates whether hardware acceleration is currently request but not * necessarily enabled yet. - * + * * @return True if requested, false otherwise. */ boolean isRequested() { @@ -696,7 +698,7 @@ public abstract class HardwareRenderer { /** * Indicates whether hardware acceleration is currently requested but not * necessarily enabled yet. - * + * * @return True to request hardware acceleration, false otherwise. */ void setRequested(boolean requested) { @@ -837,7 +839,7 @@ public abstract class HardwareRenderer { Thread mEglThread; EGLSurface mEglSurface; - + GL mGl; HardwareCanvas mCanvas; @@ -1050,7 +1052,7 @@ public abstract class HardwareRenderer { } @Override - boolean initialize(Surface surface) throws Surface.OutOfResourcesException { + boolean initialize(Surface surface) throws OutOfResourcesException { if (isRequested() && !isEnabled()) { boolean contextCreated = initializeEgl(); mGl = createEglSurface(surface); @@ -1078,9 +1080,9 @@ public abstract class HardwareRenderer { } return false; } - + @Override - void updateSurface(Surface surface) throws Surface.OutOfResourcesException { + void updateSurface(Surface surface) throws OutOfResourcesException { if (isRequested() && isEnabled()) { createEglSurface(surface); } @@ -1094,15 +1096,15 @@ public abstract class HardwareRenderer { synchronized (sEglLock) { if (sEgl == null && sEglConfig == null) { sEgl = (EGL10) EGLContext.getEGL(); - + // Get to the default display. sEglDisplay = sEgl.eglGetDisplay(EGL_DEFAULT_DISPLAY); - + if (sEglDisplay == EGL_NO_DISPLAY) { throw new RuntimeException("eglGetDisplay failed " + GLUtils.getEGLErrorString(sEgl.eglGetError())); } - + // We can now initialize EGL for that display int[] version = new int[2]; if (!sEgl.eglInitialize(sEglDisplay, version)) { @@ -1216,7 +1218,7 @@ public abstract class HardwareRenderer { Log.d(LOG_TAG, " CONFIG_CAVEAT = 0x" + Integer.toHexString(value[0])); } - GL createEglSurface(Surface surface) throws Surface.OutOfResourcesException { + GL createEglSurface(Surface surface) throws OutOfResourcesException { // Check preconditions. if (sEgl == null) { throw new RuntimeException("egl not initialized"); @@ -1228,7 +1230,7 @@ public abstract class HardwareRenderer { throw new RuntimeException("eglConfig not initialized"); } if (Thread.currentThread() != mEglThread) { - throw new IllegalStateException("HardwareRenderer cannot be used " + throw new IllegalStateException("HardwareRenderer cannot be used " + "from multiple threads"); } @@ -1394,8 +1396,8 @@ public abstract class HardwareRenderer { boolean canDraw() { return mGl != null && mCanvas != null; - } - + } + int onPreDraw(Rect dirty) { return DisplayList.STATUS_DONE; } @@ -1732,7 +1734,7 @@ public abstract class HardwareRenderer { * Ensures the current EGL context and surface are the ones we expect. * This method throws an IllegalStateException if invoked from a thread * that did not initialize EGL. - * + * * @return {@link #SURFACE_STATE_ERROR} if the correct EGL context cannot be made current, * {@link #SURFACE_STATE_UPDATED} if the EGL context was changed or * {@link #SURFACE_STATE_SUCCESS} if the EGL context was the correct one diff --git a/core/java/android/view/IApplicationToken.aidl b/core/java/android/view/IApplicationToken.aidl index 5f0600f..633b40f 100644 --- a/core/java/android/view/IApplicationToken.aidl +++ b/core/java/android/view/IApplicationToken.aidl @@ -23,7 +23,7 @@ interface IApplicationToken void windowsDrawn(); void windowsVisible(); void windowsGone(); - boolean keyDispatchingTimedOut(); + boolean keyDispatchingTimedOut(String reason); long getKeyDispatchingTimeout(); } diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index 409db84..1bfda2d 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -116,6 +116,7 @@ public class Surface implements Parcelable { * * @param surfaceTexture The {@link SurfaceTexture} that is updated by this * Surface. + * @throws OutOfResourcesException if the surface could not be created. */ public Surface(SurfaceTexture surfaceTexture) { if (surfaceTexture == null) { @@ -124,12 +125,7 @@ public class Surface implements Parcelable { synchronized (mLock) { mName = surfaceTexture.toString(); - try { - setNativeObjectLocked(nativeCreateFromSurfaceTexture(surfaceTexture)); - } catch (OutOfResourcesException ex) { - // We can't throw OutOfResourcesException because it would be an API change. - throw new RuntimeException(ex); - } + setNativeObjectLocked(nativeCreateFromSurfaceTexture(surfaceTexture)); } } @@ -229,9 +225,12 @@ public class Surface implements Parcelable { * The caller may also pass <code>null</code> instead, in the case where the * entire surface should be redrawn. * @return A canvas for drawing into the surface. + * + * @throws IllegalArgumentException If the inOutDirty rectangle is not valid. + * @throws OutOfResourcesException If the canvas cannot be locked. */ public Canvas lockCanvas(Rect inOutDirty) - throws OutOfResourcesException, IllegalArgumentException { + throws Surface.OutOfResourcesException, IllegalArgumentException { synchronized (mLock) { checkNotReleasedLocked(); if (mLockedObject != 0) { @@ -239,7 +238,7 @@ public class Surface implements Parcelable { // double-lock, but that won't happen if mNativeObject was updated. We can't // abandon the old mLockedObject because it might still be in use, so instead // we just refuse to re-lock the Surface. - throw new RuntimeException("Surface was already locked"); + throw new IllegalStateException("Surface was already locked"); } mLockedObject = nativeLockCanvas(mNativeObject, mCanvas, inOutDirty); return mCanvas; @@ -266,7 +265,7 @@ public class Surface implements Parcelable { Integer.toHexString(mLockedObject) +")"); } if (mLockedObject == 0) { - throw new RuntimeException("Surface was not locked"); + throw new IllegalStateException("Surface was not locked"); } nativeUnlockCanvasAndPost(mLockedObject, canvas); nativeRelease(mLockedObject); @@ -411,9 +410,11 @@ public class Surface implements Parcelable { } /** - * Exception thrown when a surface couldn't be created or resized. + * Exception thrown when a Canvas couldn't be locked with {@link Surface#lockCanvas}, or + * when a SurfaceTexture could not successfully be allocated. */ - public static class OutOfResourcesException extends Exception { + @SuppressWarnings("serial") + public static class OutOfResourcesException extends RuntimeException { public OutOfResourcesException() { } public OutOfResourcesException(String name) { diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index dc31e0b..b22d5cf 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -24,6 +24,7 @@ import android.view.Surface; import android.os.IBinder; import android.os.SystemProperties; import android.util.Log; +import android.view.Surface.OutOfResourcesException; /** * SurfaceControl @@ -75,23 +76,12 @@ public class SurfaceControl { private final CloseGuard mCloseGuard = CloseGuard.get(); - private String mName; + private final String mName; int mNativeObject; // package visibility only for Surface.java access private static final boolean HEADLESS = "1".equals( SystemProperties.get("ro.config.headless", "0")); - /** - * Exception thrown when a surface couldn't be created or resized. - */ - public static class OutOfResourcesException extends Exception { - public OutOfResourcesException() { - } - public OutOfResourcesException(String name) { - super(name); - } - } - /* flags used in constructor (keep in sync with ISurfaceComposerClient.h) */ /** @@ -220,6 +210,8 @@ public class SurfaceControl { * @param h The surface initial height. * @param flags The surface creation flags. Should always include {@link #HIDDEN} * in the creation flags. + * + * @throws throws OutOfResourcesException If the SurfaceControl cannot be created. */ public SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags) diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 8b2b556..1e4b29f 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -43,7 +43,7 @@ import java.util.concurrent.locks.ReentrantLock; * You can control the format of this surface and, if you like, its size; the * SurfaceView takes care of placing the surface at the correct location on the * screen - * + * * <p>The surface is Z ordered so that it is behind the window holding its * SurfaceView; the SurfaceView punches a hole in its window to allow its * surface to be displayed. The view hierarchy will take care of correctly @@ -52,7 +52,7 @@ import java.util.concurrent.locks.ReentrantLock; * buttons on top of the Surface, though note however that it can have an * impact on performance since a full alpha-blended composite will be performed * each time the Surface changes. - * + * * <p> The transparent region that makes the surface visible is based on the * layout positions in the view hierarchy. If the post-layout transform * properties are used to draw a sibling view on top of the SurfaceView, the @@ -60,16 +60,16 @@ import java.util.concurrent.locks.ReentrantLock; * * <p>Access to the underlying surface is provided via the SurfaceHolder interface, * which can be retrieved by calling {@link #getHolder}. - * + * * <p>The Surface will be created for you while the SurfaceView's window is * visible; you should implement {@link SurfaceHolder.Callback#surfaceCreated} * and {@link SurfaceHolder.Callback#surfaceDestroyed} to discover when the * Surface is created and destroyed as the window is shown and hidden. - * + * * <p>One of the purposes of this class is to provide a surface in which a * secondary thread can render into the screen. If you are going to use it * this way, you need to be aware of some threading semantics: - * + * * <ul> * <li> All SurfaceView and * {@link SurfaceHolder.Callback SurfaceHolder.Callback} methods will be called @@ -91,7 +91,7 @@ public class SurfaceView extends View { = new ArrayList<SurfaceHolder.Callback>(); final int[] mLocation = new int[2]; - + final ReentrantLock mSurfaceLock = new ReentrantLock(); final Surface mSurface = new Surface(); // Current surface in use final Surface mNewSurface = new Surface(); // New surface we are switching to @@ -106,13 +106,13 @@ public class SurfaceView extends View { final Rect mOverscanInsets = new Rect(); final Rect mContentInsets = new Rect(); final Configuration mConfiguration = new Configuration(); - + static final int KEEP_SCREEN_ON_MSG = 1; static final int GET_NEW_SURFACE_MSG = 2; static final int UPDATE_WINDOW_MSG = 3; - + int mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA; - + boolean mIsCreating = false; final Handler mHandler = new Handler() { @@ -131,14 +131,15 @@ public class SurfaceView extends View { } } }; - + final ViewTreeObserver.OnScrollChangedListener mScrollChangedListener = new ViewTreeObserver.OnScrollChangedListener() { + @Override public void onScrollChanged() { updateWindow(false, false); } }; - + boolean mRequestedVisible = false; boolean mWindowVisibility = false; boolean mViewVisibility = false; @@ -152,7 +153,7 @@ public class SurfaceView extends View { boolean mHaveFrame = false; boolean mSurfaceCreated = false; long mLastLockTime = 0; - + boolean mVisible = false; int mLeft = -1; int mTop = -1; @@ -169,7 +170,7 @@ public class SurfaceView extends View { new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { - // reposition ourselves where the surface is + // reposition ourselves where the surface is mHaveFrame = getWidth() > 0 && getHeight() > 0; updateWindow(false, false); return true; @@ -181,7 +182,7 @@ public class SurfaceView extends View { super(context); init(); } - + public SurfaceView(Context context, AttributeSet attrs) { super(context, attrs); init(); @@ -195,11 +196,11 @@ public class SurfaceView extends View { private void init() { setWillNotDraw(true); } - + /** * Return the SurfaceHolder providing access and control over this * SurfaceView's underlying surface. - * + * * @return SurfaceHolder The holder of the surface. */ public SurfaceHolder getHolder() { @@ -285,7 +286,7 @@ public class SurfaceView extends View { : getDefaultSize(0, heightMeasureSpec); setMeasuredDimension(width, height); } - + /** @hide */ @Override protected boolean setFrame(int left, int top, int right, int bottom) { @@ -299,7 +300,7 @@ public class SurfaceView extends View { if (mWindowType == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) { return super.gatherTransparentRegion(region); } - + boolean opaque = true; if ((mPrivateFlags & PFLAG_SKIP_DRAW) == 0) { // this view draws, remove it from the transparent region @@ -350,10 +351,10 @@ public class SurfaceView extends View { * regular surface view in the window (but still behind the window itself). * This is typically used to place overlays on top of an underlying media * surface view. - * + * * <p>Note that this must be set before the surface view's containing * window is attached to the window manager. - * + * * <p>Calling this overrides any previous call to {@link #setZOrderOnTop}. */ public void setZOrderMediaOverlay(boolean isMediaOverlay) { @@ -361,7 +362,7 @@ public class SurfaceView extends View { ? WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY : WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA; } - + /** * Control whether the surface view's surface is placed on top of its * window. Normally it is placed behind the window, to allow it to @@ -369,10 +370,10 @@ public class SurfaceView extends View { * hierarchy. By setting this, you cause it to be placed above the * window. This means that none of the contents of the window this * SurfaceView is in will be visible on top of its surface. - * + * * <p>Note that this must be set before the surface view's containing * window is attached to the window manager. - * + * * <p>Calling this overrides any previous call to {@link #setZOrderMediaOverlay}. */ public void setZOrderOnTop(boolean onTop) { @@ -427,7 +428,7 @@ public class SurfaceView extends View { if (mTranslator != null) { mSurface.setCompatibilityTranslator(mTranslator); } - + int myWidth = mRequestedWidth; if (myWidth <= 0) myWidth = getWidth(); int myHeight = mRequestedHeight; @@ -458,7 +459,7 @@ public class SurfaceView extends View { mFormat = mRequestedFormat; // Scaling/Translate window's layout here because mLayout is not used elsewhere. - + // Places the window relative mLayout.x = mLeft; mLayout.y = mTop; @@ -467,7 +468,7 @@ public class SurfaceView extends View { if (mTranslator != null) { mTranslator.translateLayoutParamsInAppWindowToScreen(mLayout); } - + mLayout.format = mRequestedFormat; mLayout.flags |=WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE @@ -489,7 +490,7 @@ public class SurfaceView extends View { mSession.addToDisplayWithoutInputChannel(mWindow, mWindow.mSeq, mLayout, mVisible ? VISIBLE : GONE, display.getDisplayId(), mContentInsets); } - + boolean realSizeChanged; boolean reportDrawNeeded; @@ -501,7 +502,7 @@ public class SurfaceView extends View { reportDrawNeeded = mReportDrawNeeded; mReportDrawNeeded = false; mDrawingStopped = !visible; - + if (DEBUG) Log.i(TAG, "Cur surface: " + mSurface); relayoutResult = mSession.relayout( @@ -527,7 +528,7 @@ public class SurfaceView extends View { mSurfaceFrame.right = (int) (mWinFrame.width() * appInvertedScale + 0.5f); mSurfaceFrame.bottom = (int) (mWinFrame.height() * appInvertedScale + 0.5f); } - + final int surfaceWidth = mSurfaceFrame.right; final int surfaceHeight = mSurfaceFrame.bottom; realSizeChanged = mLastSurfaceWidth != surfaceWidth @@ -667,10 +668,12 @@ public class SurfaceView extends View { } } + @Override public void dispatchAppVisibility(boolean visible) { // The point of SurfaceView is to let the app control the surface. } + @Override public void dispatchGetNewSurface() { SurfaceView surfaceView = mSurfaceView.get(); if (surfaceView != null) { @@ -679,10 +682,12 @@ public class SurfaceView extends View { } } + @Override public void windowFocusChanged(boolean hasFocus, boolean touchEnabled) { Log.w("SurfaceView", "Unexpected focus in surface: focus=" + hasFocus + ", touchEnabled=" + touchEnabled); } + @Override public void executeCommand(String command, String parameters, ParcelFileDescriptor out) { } @@ -690,30 +695,34 @@ public class SurfaceView extends View { int mCurHeight = -1; } - private SurfaceHolder mSurfaceHolder = new SurfaceHolder() { - + private final SurfaceHolder mSurfaceHolder = new SurfaceHolder() { + private static final String LOG_TAG = "SurfaceHolder"; - + + @Override public boolean isCreating() { return mIsCreating; } + @Override public void addCallback(Callback callback) { synchronized (mCallbacks) { - // This is a linear search, but in practice we'll + // This is a linear search, but in practice we'll // have only a couple callbacks, so it doesn't matter. - if (mCallbacks.contains(callback) == false) { + if (mCallbacks.contains(callback) == false) { mCallbacks.add(callback); } } } + @Override public void removeCallback(Callback callback) { synchronized (mCallbacks) { mCallbacks.remove(callback); } } - + + @Override public void setFixedSize(int width, int height) { if (mRequestedWidth != width || mRequestedHeight != height) { mRequestedWidth = width; @@ -722,6 +731,7 @@ public class SurfaceView extends View { } } + @Override public void setSizeFromLayout() { if (mRequestedWidth != -1 || mRequestedHeight != -1) { mRequestedWidth = mRequestedHeight = -1; @@ -729,6 +739,7 @@ public class SurfaceView extends View { } } + @Override public void setFormat(int format) { // for backward compatibility reason, OPAQUE always @@ -745,15 +756,17 @@ public class SurfaceView extends View { /** * @deprecated setType is now ignored. */ + @Override @Deprecated public void setType(int type) { } + @Override public void setKeepScreenOn(boolean screenOn) { Message msg = mHandler.obtainMessage(KEEP_SCREEN_ON_MSG); msg.arg1 = screenOn ? 1 : 0; mHandler.sendMessage(msg); } - + /** * Gets a {@link Canvas} for drawing into the SurfaceView's Surface * @@ -763,6 +776,7 @@ public class SurfaceView extends View { * The caller must redraw the entire surface. * @return A canvas for drawing into the surface. */ + @Override public Canvas lockCanvas() { return internalLockCanvas(null); } @@ -782,6 +796,7 @@ public class SurfaceView extends View { * entire surface should be redrawn. * @return A canvas for drawing into the surface. */ + @Override public Canvas lockCanvas(Rect inOutDirty) { return internalLockCanvas(inOutDirty); } @@ -806,7 +821,7 @@ public class SurfaceView extends View { mLastLockTime = SystemClock.uptimeMillis(); return c; } - + // If the Surface is not ready to be drawn, then return null, // but throttle calls to this function so it isn't called more // than every 100ms. @@ -821,7 +836,7 @@ public class SurfaceView extends View { } mLastLockTime = now; mSurfaceLock.unlock(); - + return null; } @@ -831,15 +846,18 @@ public class SurfaceView extends View { * * @param canvas The canvas previously obtained from {@link #lockCanvas}. */ + @Override public void unlockCanvasAndPost(Canvas canvas) { mSurface.unlockCanvasAndPost(canvas); mSurfaceLock.unlock(); } + @Override public Surface getSurface() { return mSurface; } + @Override public Rect getSurfaceFrame() { return mSurfaceFrame; } diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java index cea7e49..107d2c6 100644 --- a/core/java/android/view/ViewPropertyAnimator.java +++ b/core/java/android/view/ViewPropertyAnimator.java @@ -702,6 +702,7 @@ public class ViewPropertyAnimator { @Override public void run() { mView.setLayerType(View.LAYER_TYPE_HARDWARE, null); + mView.buildLayer(); } }; final int currentLayerType = mView.getLayerType(); diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index c7d61eb..50d5d45 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -68,6 +68,7 @@ import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.Interpolator; import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputMethodManager; +import android.view.Surface.OutOfResourcesException; import android.widget.Scroller; import com.android.internal.R; @@ -187,7 +188,7 @@ public final class ViewRootImpl implements ViewParent, InputQueue mInputQueue; FallbackEventHandler mFallbackEventHandler; Choreographer mChoreographer; - + final Rect mTempRect; // used in the transaction to not thrash the heap. final Rect mVisRect; // used to retrieve visible rect of focused view. @@ -278,8 +279,8 @@ public final class ViewRootImpl implements ViewParent, volatile Object mLocalDragState; final PointF mDragPoint = new PointF(); final PointF mLastTouchPoint = new PointF(); - - private boolean mProfileRendering; + + private boolean mProfileRendering; private Choreographer.FrameCallback mRenderProfiler; private boolean mRenderProfilingEnabled; @@ -291,7 +292,7 @@ public final class ViewRootImpl implements ViewParent, private int mFpsNumFrames; private final ArrayList<DisplayList> mDisplayLists = new ArrayList<DisplayList>(); - + /** * see {@link #playSoundEffect(int)} */ @@ -332,7 +333,7 @@ public final class ViewRootImpl implements ViewParent, int localValue; int localChanges; } - + public ViewRootImpl(Context context, Display display) { mContext = context; mWindowSession = WindowManagerGlobal.getWindowSession(); @@ -383,13 +384,13 @@ public final class ViewRootImpl implements ViewParent, } } } - + public static void addConfigCallback(ComponentCallbacks callback) { synchronized (sConfigCallbacks) { sConfigCallbacks.add(callback); } } - + // FIXME for perf testing only private boolean mProfile = false; @@ -514,7 +515,7 @@ public final class ViewRootImpl implements ViewParent, attrs.restore(); } } - + if (mTranslator != null) { mTranslator.translateRectInScreenToAppWindow(mAttachInfo.mContentInsets); } @@ -680,7 +681,7 @@ public final class ViewRootImpl implements ViewParent, if (mTranslator != null) return; // Try to enable hardware acceleration if requested - final boolean hardwareAccelerated = + final boolean hardwareAccelerated = (attrs.flags & WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0; if (hardwareAccelerated) { @@ -707,7 +708,7 @@ public final class ViewRootImpl implements ViewParent, // Don't enable hardware acceleration when we're not on the main thread if (!HardwareRenderer.sSystemRendererDisabled && Looper.getMainLooper() != Looper.myLooper()) { - Log.w(HardwareRenderer.LOG_TAG, "Attempting to initialize hardware " + Log.w(HardwareRenderer.LOG_TAG, "Attempting to initialize hardware " + "acceleration outside of the main thread, aborting"); return; } @@ -918,6 +919,7 @@ public final class ViewRootImpl implements ViewParent, return r.intersect(0, 0, mWidth, mHeight); } + @Override public void bringChildToFront(View child) { } @@ -1152,9 +1154,9 @@ public final class ViewRootImpl implements ViewParent, mLastInCompatMode = true; } } - + mWindowAttributesChangesFlag = 0; - + Rect frame = mWinFrame; if (mFirst) { mFullRedrawNeeded = true; @@ -1522,7 +1524,7 @@ public final class ViewRootImpl implements ViewParent, try { hwInitialized = mAttachInfo.mHardwareRenderer.initialize( mHolder.getSurface()); - } catch (Surface.OutOfResourcesException e) { + } catch (OutOfResourcesException e) { handleOutOfResourcesException(e); return; } @@ -1549,7 +1551,7 @@ public final class ViewRootImpl implements ViewParent, mFullRedrawNeeded = true; try { mAttachInfo.mHardwareRenderer.updateSurface(mHolder.getSurface()); - } catch (Surface.OutOfResourcesException e) { + } catch (OutOfResourcesException e) { handleOutOfResourcesException(e); return; } @@ -1644,23 +1646,23 @@ public final class ViewRootImpl implements ViewParent, || mHeight != host.getMeasuredHeight() || contentInsetsChanged) { int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width); int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height); - + if (DEBUG_LAYOUT) Log.v(TAG, "Ooops, something changed! mWidth=" + mWidth + " measuredWidth=" + host.getMeasuredWidth() + " mHeight=" + mHeight + " measuredHeight=" + host.getMeasuredHeight() + " coveredInsetsChanged=" + contentInsetsChanged); - + // Ask host how big it wants to be performMeasure(childWidthMeasureSpec, childHeightMeasureSpec); - + // Implementation of weights from WindowManager.LayoutParams // We just grow the dimensions as needed and re-measure if // needs be int width = host.getMeasuredWidth(); int height = host.getMeasuredHeight(); boolean measureAgain = false; - + if (lp.horizontalWeight > 0.0f) { width += (int) ((mWidth - width) * lp.horizontalWeight); childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(width, @@ -1673,14 +1675,14 @@ public final class ViewRootImpl implements ViewParent, MeasureSpec.EXACTLY); measureAgain = true; } - + if (measureAgain) { if (DEBUG_LAYOUT) Log.v(TAG, "And hey let's measure once more: width=" + width + " height=" + height); performMeasure(childWidthMeasureSpec, childHeightMeasureSpec); } - + layoutRequested = true; } } @@ -1851,7 +1853,7 @@ public final class ViewRootImpl implements ViewParent, } mPendingTransitions.clear(); } - + performDraw(); } } else { @@ -2078,6 +2080,7 @@ public final class ViewRootImpl implements ViewParent, return validLayoutRequesters; } + @Override public void requestTransparentRegion(View child) { // the test below should not fail unless someone is messing with us checkThread(); @@ -2128,10 +2131,12 @@ public final class ViewRootImpl implements ViewParent, int mResizeAlpha; final Paint mResizePaint = new Paint(); + @Override public void onHardwarePreDraw(HardwareCanvas canvas) { canvas.translate(0, -mHardwareYOffset); } + @Override public void onHardwarePostDraw(HardwareCanvas canvas) { if (mResizeBuffer != null) { mResizePaint.setAlpha(mResizeAlpha); @@ -2365,7 +2370,7 @@ public final class ViewRootImpl implements ViewParent, try { attachInfo.mHardwareRenderer.initializeIfNeeded(mWidth, mHeight, mHolder.getSurface()); - } catch (Surface.OutOfResourcesException e) { + } catch (OutOfResourcesException e) { handleOutOfResourcesException(e); return; } @@ -2741,6 +2746,7 @@ public final class ViewRootImpl implements ViewParent, mAccessibilityFocusedVirtualView = node; } + @Override public void requestChildFocus(View child, View focused) { if (DEBUG_INPUT_RESIZE) { Log.v(TAG, "Request child focus: focus now " + focused); @@ -2749,6 +2755,7 @@ public final class ViewRootImpl implements ViewParent, scheduleTraversals(); } + @Override public void clearChildFocus(View child) { if (DEBUG_INPUT_RESIZE) { Log.v(TAG, "Clearing child focus"); @@ -2762,6 +2769,7 @@ public final class ViewRootImpl implements ViewParent, return null; } + @Override public void focusableViewAvailable(View v) { checkThread(); if (mView != null) { @@ -2783,6 +2791,7 @@ public final class ViewRootImpl implements ViewParent, } } + @Override public void recomputeViewAttributes(View child) { checkThread(); if (mView == child) { @@ -3076,7 +3085,7 @@ public final class ViewRootImpl implements ViewParent, try { mAttachInfo.mHardwareRenderer.initializeIfNeeded( mWidth, mHeight, mHolder.getSurface()); - } catch (Surface.OutOfResourcesException e) { + } catch (OutOfResourcesException e) { Log.e(TAG, "OutOfResourcesException locking surface", e); try { if (!mWindowSession.outOfMemory(mWindow)) { @@ -4990,7 +4999,7 @@ public final class ViewRootImpl implements ViewParent, // most recent data. mSeq = args.seq; mAttachInfo.mForceReportNewAttributes = true; - scheduleTraversals(); + scheduleTraversals(); } if (mView == null) return; if (args.localChanges != 0) { @@ -5080,7 +5089,7 @@ public final class ViewRootImpl implements ViewParent, if (restore) { params.restore(); } - + if (mTranslator != null) { mTranslator.translateRectInScreenToAppWinFrame(mWinFrame); mTranslator.translateRectInScreenToAppWindow(mPendingOverscanInsets); @@ -5093,6 +5102,7 @@ public final class ViewRootImpl implements ViewParent, /** * {@inheritDoc} */ + @Override public void playSoundEffect(int effectId) { checkThread(); @@ -5133,6 +5143,7 @@ public final class ViewRootImpl implements ViewParent, /** * {@inheritDoc} */ + @Override public boolean performHapticFeedback(int effectId, boolean always) { try { return mWindowSession.performHapticFeedback(mWindow, effectId, always); @@ -5144,6 +5155,7 @@ public final class ViewRootImpl implements ViewParent, /** * {@inheritDoc} */ + @Override public View focusSearch(View focused, int direction) { checkThread(); if (!(mView instanceof ViewGroup)) { @@ -5155,7 +5167,7 @@ public final class ViewRootImpl implements ViewParent, public void debug() { mView.debug(); } - + public void dumpGfxInfo(int[] info) { info[0] = info[1] = 0; if (mView != null) { @@ -5574,8 +5586,8 @@ public final class ViewRootImpl implements ViewParent, final class InvalidateOnAnimationRunnable implements Runnable { private boolean mPosted; - private ArrayList<View> mViews = new ArrayList<View>(); - private ArrayList<AttachInfo.InvalidateInfo> mViewRects = + private final ArrayList<View> mViews = new ArrayList<View>(); + private final ArrayList<AttachInfo.InvalidateInfo> mViewRects = new ArrayList<AttachInfo.InvalidateInfo>(); private View[] mTempViews; private AttachInfo.InvalidateInfo[] mTempViewRects; @@ -5813,20 +5825,25 @@ public final class ViewRootImpl implements ViewParent, } } + @Override public boolean showContextMenuForChild(View originalView) { return false; } + @Override public ActionMode startActionModeForChild(View originalView, ActionMode.Callback callback) { return null; } + @Override public void createContextMenu(ContextMenu menu) { } + @Override public void childDrawableStateChanged(View child) { } + @Override public boolean requestSendAccessibilityEvent(View child, AccessibilityEvent event) { if (mView == null) { return false; @@ -5958,10 +5975,12 @@ public final class ViewRootImpl implements ViewParent, } } + @Override public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) { // ViewAncestor never intercepts touch event, so this can be a no-op } + @Override public boolean requestChildRectangleOnScreen(View child, Rect rectangle, boolean immediate) { final boolean scrolled = scrollToRectOrFocus(rectangle, immediate); if (rectangle != null) { @@ -5977,6 +5996,7 @@ public final class ViewRootImpl implements ViewParent, return scrolled; } + @Override public void childHasTransientStateChanged(View child, boolean hasTransientState) { // Do nothing. } @@ -5997,20 +6017,23 @@ public final class ViewRootImpl implements ViewParent, // Not currently interesting -- from changing between fixed and layout size. } + @Override public void setFormat(int format) { ((RootViewSurfaceTaker)mView).setSurfaceFormat(format); } + @Override public void setType(int type) { ((RootViewSurfaceTaker)mView).setSurfaceType(type); } - + @Override public void onUpdateSurface() { // We take care of format and type changes on our own. throw new IllegalStateException("Shouldn't be here"); } + @Override public boolean isCreating() { return mIsCreating; } @@ -6020,7 +6043,8 @@ public final class ViewRootImpl implements ViewParent, throw new UnsupportedOperationException( "Currently only support sizing from layout"); } - + + @Override public void setKeepScreenOn(boolean screenOn) { ((RootViewSurfaceTaker)mView).setSurfaceKeepScreenOn(screenOn); } @@ -6035,6 +6059,7 @@ public final class ViewRootImpl implements ViewParent, mWindowSession = viewAncestor.mWindowSession; } + @Override public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, boolean reportDraw, Configuration newConfig) { final ViewRootImpl viewAncestor = mViewAncestor.get(); @@ -6052,6 +6077,7 @@ public final class ViewRootImpl implements ViewParent, } } + @Override public void dispatchAppVisibility(boolean visible) { final ViewRootImpl viewAncestor = mViewAncestor.get(); if (viewAncestor != null) { @@ -6059,6 +6085,7 @@ public final class ViewRootImpl implements ViewParent, } } + @Override public void dispatchScreenState(boolean on) { final ViewRootImpl viewAncestor = mViewAncestor.get(); if (viewAncestor != null) { @@ -6066,6 +6093,7 @@ public final class ViewRootImpl implements ViewParent, } } + @Override public void dispatchGetNewSurface() { final ViewRootImpl viewAncestor = mViewAncestor.get(); if (viewAncestor != null) { @@ -6073,6 +6101,7 @@ public final class ViewRootImpl implements ViewParent, } } + @Override public void windowFocusChanged(boolean hasFocus, boolean inTouchMode) { final ViewRootImpl viewAncestor = mViewAncestor.get(); if (viewAncestor != null) { @@ -6089,6 +6118,7 @@ public final class ViewRootImpl implements ViewParent, } } + @Override public void executeCommand(String command, String parameters, ParcelFileDescriptor out) { final ViewRootImpl viewAncestor = mViewAncestor.get(); if (viewAncestor != null) { @@ -6119,14 +6149,16 @@ public final class ViewRootImpl implements ViewParent, } } } - + + @Override public void closeSystemDialogs(String reason) { final ViewRootImpl viewAncestor = mViewAncestor.get(); if (viewAncestor != null) { viewAncestor.dispatchCloseSystemDialogs(reason); } } - + + @Override public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep, boolean sync) { if (sync) { @@ -6137,6 +6169,7 @@ public final class ViewRootImpl implements ViewParent, } } + @Override public void dispatchWallpaperCommand(String action, int x, int y, int z, Bundle extras, boolean sync) { if (sync) { @@ -6148,6 +6181,7 @@ public final class ViewRootImpl implements ViewParent, } /* Drag/drop */ + @Override public void dispatchDragEvent(DragEvent event) { final ViewRootImpl viewAncestor = mViewAncestor.get(); if (viewAncestor != null) { @@ -6155,6 +6189,7 @@ public final class ViewRootImpl implements ViewParent, } } + @Override public void dispatchSystemUiVisibilityChanged(int seq, int globalVisibility, int localValue, int localChanges) { final ViewRootImpl viewAncestor = mViewAncestor.get(); @@ -6164,6 +6199,7 @@ public final class ViewRootImpl implements ViewParent, } } + @Override public void doneAnimating() { final ViewRootImpl viewAncestor = mViewAncestor.get(); if (viewAncestor != null) { @@ -6178,50 +6214,63 @@ public final class ViewRootImpl implements ViewParent, } } - private SurfaceHolder mHolder = new SurfaceHolder() { + private final SurfaceHolder mHolder = new SurfaceHolder() { // we only need a SurfaceHolder for opengl. it would be nice // to implement everything else though, especially the callback // support (opengl doesn't make use of it right now, but eventually // will). + @Override public Surface getSurface() { return mSurface; } + @Override public boolean isCreating() { return false; } + @Override public void addCallback(Callback callback) { } + @Override public void removeCallback(Callback callback) { } + @Override public void setFixedSize(int width, int height) { } + @Override public void setSizeFromLayout() { } + @Override public void setFormat(int format) { } + @Override public void setType(int type) { } + @Override public void setKeepScreenOn(boolean screenOn) { } + @Override public Canvas lockCanvas() { return null; } + @Override public Canvas lockCanvas(Rect dirty) { return null; } + @Override public void unlockCanvasAndPost(Canvas canvas) { } + @Override public Rect getSurfaceFrame() { return null; } @@ -6316,6 +6365,7 @@ public final class ViewRootImpl implements ViewParent, */ final class AccessibilityInteractionConnectionManager implements AccessibilityStateChangeListener { + @Override public void onAccessibilityStateChanged(boolean enabled) { if (enabled) { ensureConnection(); @@ -6491,6 +6541,7 @@ public final class ViewRootImpl implements ViewParent, public View mSource; public long mLastEventTimeMillis; + @Override public void run() { // The accessibility may be turned off while we were waiting so check again. if (AccessibilityManager.getInstance(mContext).isEnabled()) { diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java index 389d9d6..b239fbd 100644 --- a/core/java/android/widget/ListView.java +++ b/core/java/android/widget/ListView.java @@ -1555,8 +1555,9 @@ public class ListView extends AbsListView { } else if (mItemCount != mAdapter.getCount()) { throw new IllegalStateException("The content of the adapter has changed but " + "ListView did not receive a notification. Make sure the content of " - + "your adapter is not modified from a background thread, but only " - + "from the UI thread. [in ListView(" + getId() + ", " + getClass() + + "your adapter is not modified from a background thread, but only from " + + "the UI thread. Make sure your adapter calls notifyDataSetChanged() " + + "when its content changes. [in ListView(" + getId() + ", " + getClass() + ") with Adapter(" + mAdapter.getClass() + ")]"); } diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java index b87ed7a..b75d36f 100644 --- a/core/java/android/widget/Spinner.java +++ b/core/java/android/widget/Spinner.java @@ -412,6 +412,8 @@ public class Spinner extends AbsSpinner implements OnClickListener { public void setAdapter(SpinnerAdapter adapter) { super.setAdapter(adapter); + mRecycler.clear(); + if (mPopup != null) { mPopup.setAdapter(new DropDownAdapter(adapter)); } else { @@ -426,9 +428,8 @@ public class Spinner extends AbsSpinner implements OnClickListener { if (getChildCount() > 0) { child = getChildAt(0); } else if (mAdapter != null && mAdapter.getCount() > 0) { - child = makeAndAddView(0); + child = makeView(0, false); mRecycler.put(0, child); - removeAllViewsInLayout(); } if (child != null) { @@ -536,7 +537,7 @@ public class Spinner extends AbsSpinner implements OnClickListener { mFirstPosition = mSelectedPosition; if (mAdapter != null) { - View sel = makeAndAddView(mSelectedPosition); + View sel = makeView(mSelectedPosition, true); int width = sel.getMeasuredWidth(); int selectedOffset = childrenLeft; final int layoutDirection = getLayoutDirection(); @@ -571,17 +572,17 @@ public class Spinner extends AbsSpinner implements OnClickListener { * from the old to new positions. * * @param position Position in the spinner for the view to obtain - * @return A view that has been added to the spinner + * @param addChild true to add the child to the spinner, false to obtain and configure only. + * @return A view for the given position */ - private View makeAndAddView(int position) { - + private View makeView(int position, boolean addChild) { View child; if (!mDataChanged) { child = mRecycler.get(position); if (child != null) { // Position the view - setUpChild(child); + setUpChild(child, addChild); return child; } @@ -591,7 +592,7 @@ public class Spinner extends AbsSpinner implements OnClickListener { child = mAdapter.getView(position, null, this); // Position the view - setUpChild(child); + setUpChild(child, addChild); return child; } @@ -601,8 +602,9 @@ public class Spinner extends AbsSpinner implements OnClickListener { * and fill out its layout paramters. * * @param child The view to position + * @param addChild true if the child should be added to the Spinner during setup */ - private void setUpChild(View child) { + private void setUpChild(View child, boolean addChild) { // Respect layout params that are already in the view. Otherwise // make some up... @@ -611,7 +613,9 @@ public class Spinner extends AbsSpinner implements OnClickListener { lp = generateDefaultLayoutParams(); } - addViewInLayout(child, 0, lp); + if (addChild) { + addViewInLayout(child, 0, lp); + } child.setSelected(hasFocus()); if (mDisableChildrenWhenDisabled) { diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp index 1ff0d63..8cb152d 100644 --- a/core/jni/android/graphics/Graphics.cpp +++ b/core/jni/android/graphics/Graphics.cpp @@ -479,7 +479,13 @@ void AndroidPixelRef::globalRef(void* localref) { if (fWrappedPixelRef) { // delegate java obj management to the wrapped ref fWrappedPixelRef->globalRef(localref); - } else if (fOnJavaHeap && sk_atomic_inc(&fGlobalRefCnt) == 0) { + + // Note: we only ref and unref the wrapped AndroidPixelRef so that + // bitmap->pixelRef()->globalRef() and globalUnref() can be used in a pair, even if + // the bitmap has its underlying AndroidPixelRef swapped out/wrapped + return; + } + if (fOnJavaHeap && sk_atomic_inc(&fGlobalRefCnt) == 0) { JNIEnv *env = vm2env(fVM); // If JNI ref was passed, it is always used @@ -506,7 +512,9 @@ void AndroidPixelRef::globalUnref() { if (fWrappedPixelRef) { // delegate java obj management to the wrapped ref fWrappedPixelRef->globalUnref(); - } else if (fOnJavaHeap && sk_atomic_dec(&fGlobalRefCnt) == 1) { + return; + } + if (fOnJavaHeap && sk_atomic_dec(&fGlobalRefCnt) == 1) { JNIEnv *env = vm2env(fVM); if (!fHasGlobalRef) { SkDebugf("We don't have a global ref!"); diff --git a/core/jni/android/graphics/SurfaceTexture.cpp b/core/jni/android/graphics/SurfaceTexture.cpp index bacfdf6..0c9b3bc 100644 --- a/core/jni/android/graphics/SurfaceTexture.cpp +++ b/core/jni/android/graphics/SurfaceTexture.cpp @@ -37,7 +37,7 @@ namespace android { static const char* const OutOfResourcesException = - "android/graphics/SurfaceTexture$OutOfResourcesException"; + "android/view/Surface$OutOfResourcesException"; static const char* const IllegalStateException = "java/lang/IllegalStateException"; const char* const kSurfaceTextureClassPathName = "android/graphics/SurfaceTexture"; diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 2e47928..d4ca5a0 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -899,6 +899,13 @@ android:label="@string/permlab_wakeLock" android:description="@string/permdesc_wakeLock" /> + <!-- Allows using the device's IR transmitter, if available --> + <permission android:name="android.permission.TRANSMIT_IR" + android:permissionGroup="android.permission-group.AFFECTS_BATTERY" + android:protectionLevel="normal" + android:label="@string/permlab_transmitIr" + android:description="@string/permdesc_transmitIr" /> + <!-- ==================================================== --> <!-- Permissions related to changing audio settings --> <!-- ==================================================== --> @@ -1096,6 +1103,12 @@ android:description="@string/permdesc_use_sip" android:label="@string/permlab_use_sip" /> + <!-- Allows an application to request CallHandlerService implementations. --> + <permission android:name="android.permission.BIND_CALL_SERVICE" + android:permissionGroup="android.permission-group.PHONE_CALLS" + android:protectionLevel="system" /> + + <!-- ================================== --> <!-- Permissions for sdcard interaction --> <!-- ================================== --> @@ -2444,13 +2457,6 @@ android:description="@string/permdesc_accessNetworkConditions" android:protectionLevel="signature|system" /> - <!-- Allows an application to request HotwordRecognition. - @hide This is not a third-party API (intended for system apps). --> - <permission android:name="android.permission.HOTWORD_RECOGNITION" - android:label="@string/permlab_hotwordRecognition" - android:description="@string/permdesc_hotwordRecognition" - android:protectionLevel="signature|system" /> - <!-- The system process is explicitly the only one allowed to launch the confirmation UI for full backup/restore --> <uses-permission android:name="android.permission.CONFIRM_FULL_BACKUP"/> diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index 05ca120..d2ada7a 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -1379,9 +1379,6 @@ component specific values). --> <attr name="enabled" /> <attr name="exported" /> - <!-- If set to true, onProvideAssistData will be called on this service when this service - is running in the foreground. --> - <attr name="provideAssistData" format="boolean" /> <!-- If set to true, this service with be automatically stopped when the user remove a task rooted in an activity owned by the application. The default is false. --> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 1b4a083..cd1402c 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2077,6 +2077,5 @@ <public type="attr" name="supportsSwitchingToNextInputMethod" /> <public type="attr" name="requireDeviceUnlock" /> <public type="attr" name="apduServiceBanner" /> - <public type="attr" name="provideAssistData" /> </resources> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 68acd8c..fa6ecc8 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -831,7 +831,7 @@ <string name="permlab_getTopActivityInfo">get current app info</string> <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> <string name="permdesc_getTopActivityInfo">Allows the holder to retrieve private information - about the current application and services in the foreground of the screen.</string> + about the current application in the foreground of the screen.</string> <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> <string name="permlab_runSetActivityWatcher">monitor and control all app launching</string> @@ -1596,6 +1596,14 @@ <string name="permdesc_wakeLock" product="default">Allows the app to prevent the phone from going to sleep.</string> <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> + <string name="permlab_transmitIr">transmit infrared</string> + <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> + <string name="permdesc_transmitIr" product="tablet">Allows the app to use the tablet\'s infrared transmitter.</string> + <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> + <string name="permdesc_transmitIr" product="default">Allows the app to use the phone\'s infrared transmitter.</string> + + + <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> <string name="permlab_devicePower" product="tablet">power tablet on or off</string> <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> <string name="permlab_devicePower" product="default">power phone on or off</string> @@ -1911,11 +1919,6 @@ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> <string name="permdesc_accessNetworkConditions">Allows an application to listen for observations on network conditions. Should never be needed for normal apps.</string> - <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> - <string name="permlab_hotwordRecognition">request hotword recognition</string> - <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> - <string name="permdesc_hotwordRecognition">Allows an application to request for hotword recognition. Should never be needed for normal apps.</string> - <!-- Policy administration --> <!-- Title of policy access to limiting the user's password choices --> |