Loading api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -35257,6 +35257,8 @@ package android.view { public abstract class ViewAssistStructure { ctor public ViewAssistStructure(); method public abstract void asyncCommit(); method public abstract android.view.ViewAssistStructure asyncNewChild(int); method public abstract void clearExtras(); method public abstract android.os.Bundle editExtras(); method public abstract int getChildCount(); api/system-current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -37806,6 +37806,8 @@ package android.view { public abstract class ViewAssistStructure { ctor public ViewAssistStructure(); method public abstract void asyncCommit(); method public abstract android.view.ViewAssistStructure asyncNewChild(int); method public abstract void clearExtras(); method public abstract android.os.Bundle editExtras(); method public abstract int getChildCount(); core/java/android/app/AssistStructure.java +125 −13 Original line number Diff line number Diff line Loading @@ -20,11 +20,15 @@ import android.content.ComponentName; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.Typeface; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; import android.os.PooledStringReader; import android.os.PooledStringWriter; import android.os.RemoteException; import android.os.SystemClock; import android.text.TextPaint; import android.text.TextUtils; import android.util.Log; Loading @@ -49,12 +53,35 @@ final public class AssistStructure implements Parcelable { */ public static final String ASSIST_KEY = "android:assist_structure"; final ComponentName mActivityComponent; boolean mHaveData; ComponentName mActivityComponent; final ArrayList<WindowNode> mWindowNodes = new ArrayList<>(); final ArrayList<ViewNodeBuilder> mPendingAsyncChildren = new ArrayList<>(); SendChannel mSendChannel; IBinder mReceiveChannel; Rect mTmpRect = new Rect(); static final int TRANSACTION_XFER = Binder.FIRST_CALL_TRANSACTION+1; static final String DESCRIPTOR = "android.app.AssistStructure"; final class SendChannel extends Binder { @Override protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { if (code == TRANSACTION_XFER) { data.enforceInterface(DESCRIPTOR); writeContentToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); return true; } else { return super.onTransact(code, data, reply, flags); } } } final static class ViewNodeText { CharSequence mText; int mTextSelectionStart; Loading Loading @@ -112,7 +139,7 @@ final public class AssistStructure implements Parcelable { mHeight = rect.height(); mTitle = root.getTitle(); mRoot = new ViewNode(); ViewNodeBuilder builder = new ViewNodeBuilder(assist, mRoot); ViewNodeBuilder builder = new ViewNodeBuilder(assist, mRoot, false); view.dispatchProvideAssistStructure(builder); } Loading Loading @@ -425,10 +452,12 @@ final public class AssistStructure implements Parcelable { static class ViewNodeBuilder extends ViewAssistStructure { final AssistStructure mAssist; final ViewNode mNode; final boolean mAsync; ViewNodeBuilder(AssistStructure assist, ViewNode node) { ViewNodeBuilder(AssistStructure assist, ViewNode node, boolean async) { mAssist = assist; mNode = node; mAsync = async; } @Override Loading Loading @@ -628,7 +657,32 @@ final public class AssistStructure implements Parcelable { public ViewAssistStructure newChild(int index) { ViewNode node = new ViewNode(); mNode.mChildren[index] = node; return new ViewNodeBuilder(mAssist, node); return new ViewNodeBuilder(mAssist, node, false); } @Override public ViewAssistStructure asyncNewChild(int index) { synchronized (mAssist) { ViewNode node = new ViewNode(); mNode.mChildren[index] = node; ViewNodeBuilder builder = new ViewNodeBuilder(mAssist, node, true); mAssist.mPendingAsyncChildren.add(builder); return builder; } } @Override public void asyncCommit() { synchronized (mAssist) { if (!mAsync) { throw new IllegalStateException("Child " + this + " was not created with ViewAssistStructure.asyncNewChild"); } if (!mAssist.mPendingAsyncChildren.remove(this)) { throw new IllegalStateException("Child " + this + " already committed"); } mAssist.notifyAll(); } } @Override Loading @@ -638,6 +692,7 @@ final public class AssistStructure implements Parcelable { } AssistStructure(Activity activity) { mHaveData = true; mActivityComponent = activity.getComponentName(); ArrayList<ViewRootImpl> views = WindowManagerGlobal.getInstance().getRootViews( activity.getActivityToken()); Loading @@ -648,13 +703,7 @@ final public class AssistStructure implements Parcelable { } AssistStructure(Parcel in) { PooledStringReader preader = new PooledStringReader(in); mActivityComponent = ComponentName.readFromParcel(in); final int N = in.readInt(); for (int i=0; i<N; i++) { mWindowNodes.add(new WindowNode(in, preader)); } //dump(); mReceiveChannel = in.readStrongBinder(); } /** @hide */ Loading Loading @@ -731,6 +780,7 @@ final public class AssistStructure implements Parcelable { } public ComponentName getActivityComponent() { ensureData(); return mActivityComponent; } Loading @@ -738,6 +788,7 @@ final public class AssistStructure implements Parcelable { * Return the number of window contents that have been collected in this assist data. */ public int getWindowNodeCount() { ensureData(); return mWindowNodes.size(); } Loading @@ -746,6 +797,7 @@ final public class AssistStructure implements Parcelable { * @param index Which window to retrieve, may be 0 to {@link #getWindowNodeCount()}-1. */ public WindowNode getWindowNodeAt(int index) { ensureData(); return mWindowNodes.get(index); } Loading @@ -753,11 +805,47 @@ final public class AssistStructure implements Parcelable { return 0; } public void writeToParcel(Parcel out, int flags) { /** @hide */ public void ensureData() { if (mHaveData) { return; } mHaveData = true; Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(DESCRIPTOR); try { mReceiveChannel.transact(TRANSACTION_XFER, data, reply, 0); } catch (RemoteException e) { Log.w(TAG, "Failure reading AssistStructure data", e); return; } readContentFromParcel(reply); data.recycle(); reply.recycle(); } void writeContentToParcel(Parcel out, int flags) { // First make sure all content has been created. boolean skipStructure = false; synchronized (this) { long endTime = SystemClock.uptimeMillis() + 5000; long now; while (mPendingAsyncChildren.size() > 0 && (now=SystemClock.uptimeMillis()) < endTime) { try { wait(endTime-now); } catch (InterruptedException e) { } } if (mPendingAsyncChildren.size() > 0) { // We waited too long, assume none of the assist structure is valid. skipStructure = true; } } int start = out.dataPosition(); PooledStringWriter pwriter = new PooledStringWriter(out); ComponentName.writeToParcel(mActivityComponent, out); final int N = mWindowNodes.size(); final int N = skipStructure ? 0 : mWindowNodes.size(); out.writeInt(N); for (int i=0; i<N; i++) { mWindowNodes.get(i).writeToParcel(out, pwriter); Loading @@ -766,6 +854,30 @@ final public class AssistStructure implements Parcelable { Log.i(TAG, "Flattened assist data: " + (out.dataPosition() - start) + " bytes"); } void readContentFromParcel(Parcel in) { PooledStringReader preader = new PooledStringReader(in); mActivityComponent = ComponentName.readFromParcel(in); final int N = in.readInt(); for (int i=0; i<N; i++) { mWindowNodes.add(new WindowNode(in, preader)); } //dump(); } public void writeToParcel(Parcel out, int flags) { if (mHaveData) { // This object holds its data. We want to write a send channel that the // other side can use to retrieve that data. if (mSendChannel == null) { mSendChannel = new SendChannel(); } out.writeStrongBinder(mSendChannel); } else { // This object doesn't hold its data, so just propagate along its receive channel. out.writeStrongBinder(mReceiveChannel); } } public static final Parcelable.Creator<AssistStructure> CREATOR = new Parcelable.Creator<AssistStructure>() { public AssistStructure createFromParcel(Parcel in) { Loading core/java/android/service/voice/VoiceInteractionSession.java +13 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.service.voice; import android.app.AssistStructure; import android.app.Dialog; import android.app.Instrumentation; import android.app.VoiceInteractor; Loading Loading @@ -175,6 +176,18 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback { @Override public void handleAssist(Bundle assistBundle) { // We want to pre-warm the AssistStructure before handing it off to the main // thread. There is a strong argument to be made that it should be handed // through as a separate param rather than part of the assistBundle. if (assistBundle != null) { Bundle assistContext = assistBundle.getBundle(Intent.EXTRA_ASSIST_CONTEXT); if (assistContext != null) { AssistStructure as = AssistStructure.getAssistStructure(assistContext); if (as != null) { as.ensureData(); } } } mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageO(MSG_HANDLE_ASSIST, assistBundle)); } Loading core/java/android/view/ViewAssistStructure.java +3 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,9 @@ public abstract class ViewAssistStructure { public abstract int getChildCount(); public abstract ViewAssistStructure newChild(int index); public abstract ViewAssistStructure asyncNewChild(int index); public abstract void asyncCommit(); /** @hide */ public abstract Rect getTempRect(); } Loading
api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -35257,6 +35257,8 @@ package android.view { public abstract class ViewAssistStructure { ctor public ViewAssistStructure(); method public abstract void asyncCommit(); method public abstract android.view.ViewAssistStructure asyncNewChild(int); method public abstract void clearExtras(); method public abstract android.os.Bundle editExtras(); method public abstract int getChildCount();
api/system-current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -37806,6 +37806,8 @@ package android.view { public abstract class ViewAssistStructure { ctor public ViewAssistStructure(); method public abstract void asyncCommit(); method public abstract android.view.ViewAssistStructure asyncNewChild(int); method public abstract void clearExtras(); method public abstract android.os.Bundle editExtras(); method public abstract int getChildCount();
core/java/android/app/AssistStructure.java +125 −13 Original line number Diff line number Diff line Loading @@ -20,11 +20,15 @@ import android.content.ComponentName; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.Typeface; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; import android.os.PooledStringReader; import android.os.PooledStringWriter; import android.os.RemoteException; import android.os.SystemClock; import android.text.TextPaint; import android.text.TextUtils; import android.util.Log; Loading @@ -49,12 +53,35 @@ final public class AssistStructure implements Parcelable { */ public static final String ASSIST_KEY = "android:assist_structure"; final ComponentName mActivityComponent; boolean mHaveData; ComponentName mActivityComponent; final ArrayList<WindowNode> mWindowNodes = new ArrayList<>(); final ArrayList<ViewNodeBuilder> mPendingAsyncChildren = new ArrayList<>(); SendChannel mSendChannel; IBinder mReceiveChannel; Rect mTmpRect = new Rect(); static final int TRANSACTION_XFER = Binder.FIRST_CALL_TRANSACTION+1; static final String DESCRIPTOR = "android.app.AssistStructure"; final class SendChannel extends Binder { @Override protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { if (code == TRANSACTION_XFER) { data.enforceInterface(DESCRIPTOR); writeContentToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); return true; } else { return super.onTransact(code, data, reply, flags); } } } final static class ViewNodeText { CharSequence mText; int mTextSelectionStart; Loading Loading @@ -112,7 +139,7 @@ final public class AssistStructure implements Parcelable { mHeight = rect.height(); mTitle = root.getTitle(); mRoot = new ViewNode(); ViewNodeBuilder builder = new ViewNodeBuilder(assist, mRoot); ViewNodeBuilder builder = new ViewNodeBuilder(assist, mRoot, false); view.dispatchProvideAssistStructure(builder); } Loading Loading @@ -425,10 +452,12 @@ final public class AssistStructure implements Parcelable { static class ViewNodeBuilder extends ViewAssistStructure { final AssistStructure mAssist; final ViewNode mNode; final boolean mAsync; ViewNodeBuilder(AssistStructure assist, ViewNode node) { ViewNodeBuilder(AssistStructure assist, ViewNode node, boolean async) { mAssist = assist; mNode = node; mAsync = async; } @Override Loading Loading @@ -628,7 +657,32 @@ final public class AssistStructure implements Parcelable { public ViewAssistStructure newChild(int index) { ViewNode node = new ViewNode(); mNode.mChildren[index] = node; return new ViewNodeBuilder(mAssist, node); return new ViewNodeBuilder(mAssist, node, false); } @Override public ViewAssistStructure asyncNewChild(int index) { synchronized (mAssist) { ViewNode node = new ViewNode(); mNode.mChildren[index] = node; ViewNodeBuilder builder = new ViewNodeBuilder(mAssist, node, true); mAssist.mPendingAsyncChildren.add(builder); return builder; } } @Override public void asyncCommit() { synchronized (mAssist) { if (!mAsync) { throw new IllegalStateException("Child " + this + " was not created with ViewAssistStructure.asyncNewChild"); } if (!mAssist.mPendingAsyncChildren.remove(this)) { throw new IllegalStateException("Child " + this + " already committed"); } mAssist.notifyAll(); } } @Override Loading @@ -638,6 +692,7 @@ final public class AssistStructure implements Parcelable { } AssistStructure(Activity activity) { mHaveData = true; mActivityComponent = activity.getComponentName(); ArrayList<ViewRootImpl> views = WindowManagerGlobal.getInstance().getRootViews( activity.getActivityToken()); Loading @@ -648,13 +703,7 @@ final public class AssistStructure implements Parcelable { } AssistStructure(Parcel in) { PooledStringReader preader = new PooledStringReader(in); mActivityComponent = ComponentName.readFromParcel(in); final int N = in.readInt(); for (int i=0; i<N; i++) { mWindowNodes.add(new WindowNode(in, preader)); } //dump(); mReceiveChannel = in.readStrongBinder(); } /** @hide */ Loading Loading @@ -731,6 +780,7 @@ final public class AssistStructure implements Parcelable { } public ComponentName getActivityComponent() { ensureData(); return mActivityComponent; } Loading @@ -738,6 +788,7 @@ final public class AssistStructure implements Parcelable { * Return the number of window contents that have been collected in this assist data. */ public int getWindowNodeCount() { ensureData(); return mWindowNodes.size(); } Loading @@ -746,6 +797,7 @@ final public class AssistStructure implements Parcelable { * @param index Which window to retrieve, may be 0 to {@link #getWindowNodeCount()}-1. */ public WindowNode getWindowNodeAt(int index) { ensureData(); return mWindowNodes.get(index); } Loading @@ -753,11 +805,47 @@ final public class AssistStructure implements Parcelable { return 0; } public void writeToParcel(Parcel out, int flags) { /** @hide */ public void ensureData() { if (mHaveData) { return; } mHaveData = true; Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(DESCRIPTOR); try { mReceiveChannel.transact(TRANSACTION_XFER, data, reply, 0); } catch (RemoteException e) { Log.w(TAG, "Failure reading AssistStructure data", e); return; } readContentFromParcel(reply); data.recycle(); reply.recycle(); } void writeContentToParcel(Parcel out, int flags) { // First make sure all content has been created. boolean skipStructure = false; synchronized (this) { long endTime = SystemClock.uptimeMillis() + 5000; long now; while (mPendingAsyncChildren.size() > 0 && (now=SystemClock.uptimeMillis()) < endTime) { try { wait(endTime-now); } catch (InterruptedException e) { } } if (mPendingAsyncChildren.size() > 0) { // We waited too long, assume none of the assist structure is valid. skipStructure = true; } } int start = out.dataPosition(); PooledStringWriter pwriter = new PooledStringWriter(out); ComponentName.writeToParcel(mActivityComponent, out); final int N = mWindowNodes.size(); final int N = skipStructure ? 0 : mWindowNodes.size(); out.writeInt(N); for (int i=0; i<N; i++) { mWindowNodes.get(i).writeToParcel(out, pwriter); Loading @@ -766,6 +854,30 @@ final public class AssistStructure implements Parcelable { Log.i(TAG, "Flattened assist data: " + (out.dataPosition() - start) + " bytes"); } void readContentFromParcel(Parcel in) { PooledStringReader preader = new PooledStringReader(in); mActivityComponent = ComponentName.readFromParcel(in); final int N = in.readInt(); for (int i=0; i<N; i++) { mWindowNodes.add(new WindowNode(in, preader)); } //dump(); } public void writeToParcel(Parcel out, int flags) { if (mHaveData) { // This object holds its data. We want to write a send channel that the // other side can use to retrieve that data. if (mSendChannel == null) { mSendChannel = new SendChannel(); } out.writeStrongBinder(mSendChannel); } else { // This object doesn't hold its data, so just propagate along its receive channel. out.writeStrongBinder(mReceiveChannel); } } public static final Parcelable.Creator<AssistStructure> CREATOR = new Parcelable.Creator<AssistStructure>() { public AssistStructure createFromParcel(Parcel in) { Loading
core/java/android/service/voice/VoiceInteractionSession.java +13 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.service.voice; import android.app.AssistStructure; import android.app.Dialog; import android.app.Instrumentation; import android.app.VoiceInteractor; Loading Loading @@ -175,6 +176,18 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback { @Override public void handleAssist(Bundle assistBundle) { // We want to pre-warm the AssistStructure before handing it off to the main // thread. There is a strong argument to be made that it should be handed // through as a separate param rather than part of the assistBundle. if (assistBundle != null) { Bundle assistContext = assistBundle.getBundle(Intent.EXTRA_ASSIST_CONTEXT); if (assistContext != null) { AssistStructure as = AssistStructure.getAssistStructure(assistContext); if (as != null) { as.ensureData(); } } } mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageO(MSG_HANDLE_ASSIST, assistBundle)); } Loading
core/java/android/view/ViewAssistStructure.java +3 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,9 @@ public abstract class ViewAssistStructure { public abstract int getChildCount(); public abstract ViewAssistStructure newChild(int index); public abstract ViewAssistStructure asyncNewChild(int index); public abstract void asyncCommit(); /** @hide */ public abstract Rect getTempRect(); }