2323
2424import java .io .FileDescriptor ;
2525import java .io .PrintWriter ;
26+ import java .lang .ref .WeakReference ;
2627import java .util .concurrent .CountDownLatch ;
2728import java .util .concurrent .TimeUnit ;
2829
@@ -48,9 +49,9 @@ class IInputMethodWrapper extends IInputMethod.Stub
4849 private static final int DO_SHOW_SOFT_INPUT = 60 ;
4950 private static final int DO_HIDE_SOFT_INPUT = 70 ;
5051
51- final AbstractInputMethodService mTarget ;
52+ final WeakReference < AbstractInputMethodService > mTarget ;
5253 final HandlerCaller mCaller ;
53- final InputMethod mInputMethod ;
54+ final WeakReference < InputMethod > mInputMethod ;
5455
5556 static class Notifier {
5657 boolean notified ;
@@ -80,21 +81,32 @@ public void sessionCreated(InputMethodSession session) {
8081
8182 public IInputMethodWrapper (AbstractInputMethodService context ,
8283 InputMethod inputMethod ) {
83- mTarget = context ;
84- mCaller = new HandlerCaller (context , this );
85- mInputMethod = inputMethod ;
84+ mTarget = new WeakReference < AbstractInputMethodService >( context ) ;
85+ mCaller = new HandlerCaller (context . getApplicationContext () , this );
86+ mInputMethod = new WeakReference < InputMethod >( inputMethod ) ;
8687 }
8788
8889 public InputMethod getInternalInputMethod () {
89- return mInputMethod ;
90+ return mInputMethod . get () ;
9091 }
9192
9293 public void executeMessage (Message msg ) {
94+ InputMethod inputMethod = mInputMethod .get ();
95+ // Need a valid reference to the inputMethod for everything except a dump.
96+ if (inputMethod == null && msg .what != DO_DUMP ) {
97+ Log .w (TAG , "Input method reference was null, ignoring message: " + msg .what );
98+ return ;
99+ }
100+
93101 switch (msg .what ) {
94102 case DO_DUMP : {
103+ AbstractInputMethodService target = mTarget .get ();
104+ if (target == null ) {
105+ return ;
106+ }
95107 HandlerCaller .SomeArgs args = (HandlerCaller .SomeArgs )msg .obj ;
96108 try {
97- mTarget .dump ((FileDescriptor )args .arg1 ,
109+ target .dump ((FileDescriptor )args .arg1 ,
98110 (PrintWriter )args .arg2 , (String [])args .arg3 );
99111 } catch (RuntimeException e ) {
100112 ((PrintWriter )args .arg2 ).println ("Exception: " + e );
@@ -106,56 +118,60 @@ public void executeMessage(Message msg) {
106118 }
107119
108120 case DO_ATTACH_TOKEN : {
109- mInputMethod .attachToken ((IBinder )msg .obj );
121+ inputMethod .attachToken ((IBinder )msg .obj );
110122 return ;
111123 }
112124 case DO_SET_INPUT_CONTEXT : {
113- mInputMethod .bindInput ((InputBinding )msg .obj );
125+ inputMethod .bindInput ((InputBinding )msg .obj );
114126 return ;
115127 }
116128 case DO_UNSET_INPUT_CONTEXT :
117- mInputMethod .unbindInput ();
129+ inputMethod .unbindInput ();
118130 return ;
119131 case DO_START_INPUT : {
120132 HandlerCaller .SomeArgs args = (HandlerCaller .SomeArgs )msg .obj ;
121133 IInputContext inputContext = (IInputContext )args .arg1 ;
122134 InputConnection ic = inputContext != null
123135 ? new InputConnectionWrapper (inputContext ) : null ;
124- mInputMethod .startInput (ic , (EditorInfo )args .arg2 );
136+ inputMethod .startInput (ic , (EditorInfo )args .arg2 );
125137 return ;
126138 }
127139 case DO_RESTART_INPUT : {
128140 HandlerCaller .SomeArgs args = (HandlerCaller .SomeArgs )msg .obj ;
129141 IInputContext inputContext = (IInputContext )args .arg1 ;
130142 InputConnection ic = inputContext != null
131143 ? new InputConnectionWrapper (inputContext ) : null ;
132- mInputMethod .restartInput (ic , (EditorInfo )args .arg2 );
144+ inputMethod .restartInput (ic , (EditorInfo )args .arg2 );
133145 return ;
134146 }
135147 case DO_CREATE_SESSION : {
136- mInputMethod .createSession (new InputMethodSessionCallbackWrapper (
148+ inputMethod .createSession (new InputMethodSessionCallbackWrapper (
137149 mCaller .mContext , (IInputMethodCallback )msg .obj ));
138150 return ;
139151 }
140152 case DO_SET_SESSION_ENABLED :
141- mInputMethod .setSessionEnabled ((InputMethodSession )msg .obj ,
153+ inputMethod .setSessionEnabled ((InputMethodSession )msg .obj ,
142154 msg .arg1 != 0 );
143155 return ;
144156 case DO_REVOKE_SESSION :
145- mInputMethod .revokeSession ((InputMethodSession )msg .obj );
157+ inputMethod .revokeSession ((InputMethodSession )msg .obj );
146158 return ;
147159 case DO_SHOW_SOFT_INPUT :
148- mInputMethod .showSoftInput (msg .arg1 , (ResultReceiver )msg .obj );
160+ inputMethod .showSoftInput (msg .arg1 , (ResultReceiver )msg .obj );
149161 return ;
150162 case DO_HIDE_SOFT_INPUT :
151- mInputMethod .hideSoftInput (msg .arg1 , (ResultReceiver )msg .obj );
163+ inputMethod .hideSoftInput (msg .arg1 , (ResultReceiver )msg .obj );
152164 return ;
153165 }
154166 Log .w (TAG , "Unhandled message code: " + msg .what );
155167 }
156168
157169 @ Override protected void dump (FileDescriptor fd , PrintWriter fout , String [] args ) {
158- if (mTarget .checkCallingOrSelfPermission (android .Manifest .permission .DUMP )
170+ AbstractInputMethodService target = mTarget .get ();
171+ if (target == null ) {
172+ return ;
173+ }
174+ if (target .checkCallingOrSelfPermission (android .Manifest .permission .DUMP )
159175 != PackageManager .PERMISSION_GRANTED ) {
160176
161177 fout .println ("Permission Denial: can't dump InputMethodManager from from pid="
0 commit comments