diff options
Diffstat (limited to 'core/java/android')
35 files changed, 351 insertions, 1076 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 6b24e6b..370db31 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -1937,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; } @@ -4492,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 64054c5..3e4795c 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -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 4f930b5..8e9f3bb 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -184,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; @@ -685,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) { @@ -1967,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; @@ -1983,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(); @@ -2017,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 e362afb..b2ae298 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -389,8 +389,7 @@ public interface IActivityManager extends IInterface { 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 a2ccb5b..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(); 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/nfc/cardemulation/ApduServiceInfo.java b/core/java/android/nfc/cardemulation/ApduServiceInfo.java index d3e5752..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) @@ -141,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); @@ -148,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>(); @@ -183,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) { @@ -206,6 +220,7 @@ public final class ApduServiceInfo implements Parcelable { } else { Log.e(TAG, "Ignoring invalid or duplicate aid: " + aid); } + a.recycle(); } } } catch (NameNotFoundException e) { @@ -248,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; @@ -302,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 = @@ -317,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/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/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/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/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()) { |
