blob: 48ec420bb435f45b12b26c8f43a4061db071f5dc [file] [log] [blame]
Craig Mautner4504de52013-12-20 09:06:56 -08001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.app;
18
19import android.content.Context;
20import android.content.ContextWrapper;
Craig Mautner4e5b67e2014-02-07 15:30:03 -080021import android.content.IIntentSender;
Craig Mautner4504de52013-12-20 09:06:56 -080022import android.content.Intent;
Craig Mautnerdf88d732014-01-27 09:21:32 -080023import android.content.IntentSender;
Craig Mautner4504de52013-12-20 09:06:56 -080024import android.graphics.SurfaceTexture;
25import android.os.IBinder;
26import android.os.RemoteException;
27import android.util.AttributeSet;
28import android.util.DisplayMetrics;
Craig Mautner34b73df2014-01-12 21:11:08 -080029import android.util.Log;
Jeff Brown38f96e52014-02-11 14:32:56 -080030import android.view.InputDevice;
31import android.view.InputEvent;
32import android.view.MotionEvent;
Craig Mautner4504de52013-12-20 09:06:56 -080033import android.view.Surface;
34import android.view.TextureView;
35import android.view.TextureView.SurfaceTextureListener;
Craig Mautnerdf88d732014-01-27 09:21:32 -080036import android.view.View;
Craig Mautner4504de52013-12-20 09:06:56 -080037import android.view.ViewGroup;
38import android.view.WindowManager;
39
40public class ActivityView extends ViewGroup {
Craig Mautner34b73df2014-01-12 21:11:08 -080041 private final String TAG = "ActivityView";
42
Craig Mautner4504de52013-12-20 09:06:56 -080043 private final TextureView mTextureView;
44 private IActivityContainer mActivityContainer;
45 private Activity mActivity;
Craig Mautner4504de52013-12-20 09:06:56 -080046 private int mWidth;
47 private int mHeight;
Craig Mautner34b73df2014-01-12 21:11:08 -080048 private Surface mSurface;
Craig Mautner4504de52013-12-20 09:06:56 -080049
Craig Mautner4e5b67e2014-02-07 15:30:03 -080050 // Only one IIntentSender or Intent may be queued at a time. Most recent one wins.
51 IIntentSender mQueuedPendingIntent;
52 Intent mQueuedIntent;
53
Craig Mautner4504de52013-12-20 09:06:56 -080054 public ActivityView(Context context) {
55 this(context, null);
56 }
57
58 public ActivityView(Context context, AttributeSet attrs) {
59 this(context, attrs, 0);
60 }
61
62 public ActivityView(Context context, AttributeSet attrs, int defStyle) {
63 super(context, attrs, defStyle);
64
65 while (context instanceof ContextWrapper) {
66 if (context instanceof Activity) {
67 mActivity = (Activity)context;
68 break;
69 }
70 context = ((ContextWrapper)context).getBaseContext();
71 }
72 if (mActivity == null) {
73 throw new IllegalStateException("The ActivityView's Context is not an Activity.");
74 }
75
76 mTextureView = new TextureView(context);
77 mTextureView.setSurfaceTextureListener(new ActivityViewSurfaceTextureListener());
78 addView(mTextureView);
79 }
80
81 @Override
82 protected void onLayout(boolean changed, int l, int t, int r, int b) {
Griff Hazenaf745f62014-02-10 08:58:32 -080083 mTextureView.layout(0, 0, r - l, b - t);
Craig Mautner4504de52013-12-20 09:06:56 -080084 }
85
86 @Override
87 protected void onAttachedToWindow() {
88 try {
89 final IBinder token = mActivity.getActivityToken();
90 mActivityContainer =
91 ActivityManagerNative.getDefault().createActivityContainer(token, null);
92 } catch (RemoteException e) {
93 throw new IllegalStateException("ActivityView: Unable to create ActivityContainer. "
94 + e);
95 }
96
Craig Mautnerdf88d732014-01-27 09:21:32 -080097 attachToSurfaceWhenReady();
Craig Mautner4504de52013-12-20 09:06:56 -080098 }
99
100 @Override
101 protected void onDetachedFromWindow() {
Craig Mautnerdf88d732014-01-27 09:21:32 -0800102 if (mActivityContainer != null) {
103 detach();
104 mActivityContainer = null;
105 }
Craig Mautner34b73df2014-01-12 21:11:08 -0800106 }
107
108 @Override
Craig Mautnerdf88d732014-01-27 09:21:32 -0800109 protected void onWindowVisibilityChanged(int visibility) {
110 super.onWindowVisibilityChanged(visibility);
111 if (visibility == View.VISIBLE) {
112 attachToSurfaceWhenReady();
113 } else {
114 detach();
115 }
116 }
117
Jeff Brown38f96e52014-02-11 14:32:56 -0800118 private boolean injectInputEvent(InputEvent event) {
119 try {
120 return mActivityContainer != null && mActivityContainer.injectEvent(event);
121 } catch (RemoteException e) {
122 return false;
123 }
124 }
125
126 @Override
127 public boolean onTouchEvent(MotionEvent event) {
128 return injectInputEvent(event) || super.onTouchEvent(event);
129 }
130
131 @Override
132 public boolean onGenericMotionEvent(MotionEvent event) {
133 if (event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
134 if (injectInputEvent(event)) {
135 return true;
136 }
137 }
138 return super.onGenericMotionEvent(event);
139 }
140
Craig Mautnerdf88d732014-01-27 09:21:32 -0800141 public boolean isAttachedToDisplay() {
142 return mSurface != null;
Craig Mautner4504de52013-12-20 09:06:56 -0800143 }
144
145 public void startActivity(Intent intent) {
Craig Mautnerdf88d732014-01-27 09:21:32 -0800146 if (mSurface != null) {
Craig Mautner4504de52013-12-20 09:06:56 -0800147 try {
148 mActivityContainer.startActivity(intent);
149 } catch (RemoteException e) {
150 throw new IllegalStateException("ActivityView: Unable to startActivity. " + e);
151 }
Craig Mautner4e5b67e2014-02-07 15:30:03 -0800152 } else {
153 mQueuedIntent = intent;
154 mQueuedPendingIntent = null;
155 }
156 }
157
158 private void startActivityIntentSender(IIntentSender iIntentSender) {
159 try {
160 mActivityContainer.startActivityIntentSender(iIntentSender);
161 } catch (RemoteException e) {
162 throw new IllegalStateException(
163 "ActivityView: Unable to startActivity from IntentSender. " + e);
Craig Mautner4504de52013-12-20 09:06:56 -0800164 }
165 }
166
Craig Mautnerdf88d732014-01-27 09:21:32 -0800167 public void startActivity(IntentSender intentSender) {
Craig Mautner4e5b67e2014-02-07 15:30:03 -0800168 final IIntentSender iIntentSender = intentSender.getTarget();
Craig Mautnerdf88d732014-01-27 09:21:32 -0800169 if (mSurface != null) {
Craig Mautner4e5b67e2014-02-07 15:30:03 -0800170 startActivityIntentSender(iIntentSender);
171 } else {
172 mQueuedPendingIntent = iIntentSender;
173 mQueuedIntent = null;
Craig Mautnerdf88d732014-01-27 09:21:32 -0800174 }
175 }
176
177 public void startActivity(PendingIntent pendingIntent) {
Craig Mautner4e5b67e2014-02-07 15:30:03 -0800178 final IIntentSender iIntentSender = pendingIntent.getTarget();
Craig Mautnerdf88d732014-01-27 09:21:32 -0800179 if (mSurface != null) {
Craig Mautner4e5b67e2014-02-07 15:30:03 -0800180 startActivityIntentSender(iIntentSender);
181 } else {
182 mQueuedPendingIntent = iIntentSender;
183 mQueuedIntent = null;
Craig Mautnerdf88d732014-01-27 09:21:32 -0800184 }
185 }
186
187 private void attachToSurfaceWhenReady() {
188 final SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
189 if (mActivityContainer == null || surfaceTexture == null || mSurface != null) {
190 // Either not ready to attach, or already attached.
191 return;
192 }
193
Craig Mautner4504de52013-12-20 09:06:56 -0800194 WindowManager wm = (WindowManager)mActivity.getSystemService(Context.WINDOW_SERVICE);
195 DisplayMetrics metrics = new DisplayMetrics();
196 wm.getDefaultDisplay().getMetrics(metrics);
197
Craig Mautner34b73df2014-01-12 21:11:08 -0800198 mSurface = new Surface(surfaceTexture);
Craig Mautner4504de52013-12-20 09:06:56 -0800199 try {
Craig Mautnerdf88d732014-01-27 09:21:32 -0800200 mActivityContainer.attachToSurface(mSurface, mWidth, mHeight, metrics.densityDpi);
Craig Mautner4504de52013-12-20 09:06:56 -0800201 } catch (RemoteException e) {
Craig Mautner34b73df2014-01-12 21:11:08 -0800202 mSurface.release();
203 mSurface = null;
Craig Mautner4504de52013-12-20 09:06:56 -0800204 throw new IllegalStateException(
205 "ActivityView: Unable to create ActivityContainer. " + e);
206 }
Craig Mautner4e5b67e2014-02-07 15:30:03 -0800207
208 if (mQueuedIntent != null) {
209 startActivity(mQueuedIntent);
210 mQueuedIntent = null;
211 } else if (mQueuedPendingIntent != null) {
212 startActivityIntentSender(mQueuedPendingIntent);
213 mQueuedPendingIntent = null;
214 }
Craig Mautner4504de52013-12-20 09:06:56 -0800215 }
216
Craig Mautnerdf88d732014-01-27 09:21:32 -0800217 private void detach() {
218 if (mSurface != null) {
Craig Mautner34b73df2014-01-12 21:11:08 -0800219 try {
220 mActivityContainer.detachFromDisplay();
221 } catch (RemoteException e) {
222 }
Craig Mautner34b73df2014-01-12 21:11:08 -0800223 mSurface.release();
224 mSurface = null;
225 }
Craig Mautner34b73df2014-01-12 21:11:08 -0800226 }
227
Craig Mautner4504de52013-12-20 09:06:56 -0800228 private class ActivityViewSurfaceTextureListener implements SurfaceTextureListener {
229 @Override
230 public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width,
231 int height) {
232 mWidth = width;
233 mHeight = height;
234 if (mActivityContainer != null) {
Craig Mautnerdf88d732014-01-27 09:21:32 -0800235 attachToSurfaceWhenReady();
Craig Mautner4504de52013-12-20 09:06:56 -0800236 }
237 }
238
239 @Override
240 public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width,
241 int height) {
Craig Mautner34b73df2014-01-12 21:11:08 -0800242 Log.d(TAG, "onSurfaceTextureSizeChanged: w=" + width + " h=" + height);
Craig Mautner4504de52013-12-20 09:06:56 -0800243 }
244
245 @Override
246 public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
Craig Mautner34b73df2014-01-12 21:11:08 -0800247 Log.d(TAG, "onSurfaceTextureDestroyed");
Craig Mautnerdf88d732014-01-27 09:21:32 -0800248 detach();
Craig Mautner34b73df2014-01-12 21:11:08 -0800249 return true;
Craig Mautner4504de52013-12-20 09:06:56 -0800250 }
251
252 @Override
253 public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
Craig Mautner34b73df2014-01-12 21:11:08 -0800254// Log.d(TAG, "onSurfaceTextureUpdated");
Craig Mautner4504de52013-12-20 09:06:56 -0800255 }
256
257 }
258}