blob: ad384898407edf51c7419f5cac9afa47f4ce9dab [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;
Craig Mautner4504de52013-12-20 09:06:56 -080030import android.view.Surface;
31import android.view.TextureView;
32import android.view.TextureView.SurfaceTextureListener;
Craig Mautnerdf88d732014-01-27 09:21:32 -080033import android.view.View;
Craig Mautner4504de52013-12-20 09:06:56 -080034import android.view.ViewGroup;
35import android.view.WindowManager;
36
37public class ActivityView extends ViewGroup {
Craig Mautner34b73df2014-01-12 21:11:08 -080038 private final String TAG = "ActivityView";
39
Craig Mautner4504de52013-12-20 09:06:56 -080040 private final TextureView mTextureView;
41 private IActivityContainer mActivityContainer;
42 private Activity mActivity;
Craig Mautner4504de52013-12-20 09:06:56 -080043 private int mWidth;
44 private int mHeight;
Craig Mautner34b73df2014-01-12 21:11:08 -080045 private Surface mSurface;
Craig Mautner4504de52013-12-20 09:06:56 -080046
Craig Mautner4e5b67e2014-02-07 15:30:03 -080047 // Only one IIntentSender or Intent may be queued at a time. Most recent one wins.
48 IIntentSender mQueuedPendingIntent;
49 Intent mQueuedIntent;
50
Craig Mautner4504de52013-12-20 09:06:56 -080051 public ActivityView(Context context) {
52 this(context, null);
53 }
54
55 public ActivityView(Context context, AttributeSet attrs) {
56 this(context, attrs, 0);
57 }
58
59 public ActivityView(Context context, AttributeSet attrs, int defStyle) {
60 super(context, attrs, defStyle);
61
62 while (context instanceof ContextWrapper) {
63 if (context instanceof Activity) {
64 mActivity = (Activity)context;
65 break;
66 }
67 context = ((ContextWrapper)context).getBaseContext();
68 }
69 if (mActivity == null) {
70 throw new IllegalStateException("The ActivityView's Context is not an Activity.");
71 }
72
73 mTextureView = new TextureView(context);
74 mTextureView.setSurfaceTextureListener(new ActivityViewSurfaceTextureListener());
75 addView(mTextureView);
76 }
77
78 @Override
79 protected void onLayout(boolean changed, int l, int t, int r, int b) {
80 mTextureView.layout(l, t, r, b);
81 }
82
83 @Override
84 protected void onAttachedToWindow() {
85 try {
86 final IBinder token = mActivity.getActivityToken();
87 mActivityContainer =
88 ActivityManagerNative.getDefault().createActivityContainer(token, null);
89 } catch (RemoteException e) {
90 throw new IllegalStateException("ActivityView: Unable to create ActivityContainer. "
91 + e);
92 }
93
Craig Mautnerdf88d732014-01-27 09:21:32 -080094 attachToSurfaceWhenReady();
Craig Mautner4504de52013-12-20 09:06:56 -080095 }
96
97 @Override
98 protected void onDetachedFromWindow() {
Craig Mautnerdf88d732014-01-27 09:21:32 -080099 if (mActivityContainer != null) {
100 detach();
101 mActivityContainer = null;
102 }
Craig Mautner34b73df2014-01-12 21:11:08 -0800103 }
104
105 @Override
Craig Mautnerdf88d732014-01-27 09:21:32 -0800106 protected void onWindowVisibilityChanged(int visibility) {
107 super.onWindowVisibilityChanged(visibility);
108 if (visibility == View.VISIBLE) {
109 attachToSurfaceWhenReady();
110 } else {
111 detach();
112 }
113 }
114
115 public boolean isAttachedToDisplay() {
116 return mSurface != null;
Craig Mautner4504de52013-12-20 09:06:56 -0800117 }
118
119 public void startActivity(Intent intent) {
Craig Mautnerdf88d732014-01-27 09:21:32 -0800120 if (mSurface != null) {
Craig Mautner4504de52013-12-20 09:06:56 -0800121 try {
122 mActivityContainer.startActivity(intent);
123 } catch (RemoteException e) {
124 throw new IllegalStateException("ActivityView: Unable to startActivity. " + e);
125 }
Craig Mautner4e5b67e2014-02-07 15:30:03 -0800126 } else {
127 mQueuedIntent = intent;
128 mQueuedPendingIntent = null;
129 }
130 }
131
132 private void startActivityIntentSender(IIntentSender iIntentSender) {
133 try {
134 mActivityContainer.startActivityIntentSender(iIntentSender);
135 } catch (RemoteException e) {
136 throw new IllegalStateException(
137 "ActivityView: Unable to startActivity from IntentSender. " + e);
Craig Mautner4504de52013-12-20 09:06:56 -0800138 }
139 }
140
Craig Mautnerdf88d732014-01-27 09:21:32 -0800141 public void startActivity(IntentSender intentSender) {
Craig Mautner4e5b67e2014-02-07 15:30:03 -0800142 final IIntentSender iIntentSender = intentSender.getTarget();
Craig Mautnerdf88d732014-01-27 09:21:32 -0800143 if (mSurface != null) {
Craig Mautner4e5b67e2014-02-07 15:30:03 -0800144 startActivityIntentSender(iIntentSender);
145 } else {
146 mQueuedPendingIntent = iIntentSender;
147 mQueuedIntent = null;
Craig Mautnerdf88d732014-01-27 09:21:32 -0800148 }
149 }
150
151 public void startActivity(PendingIntent pendingIntent) {
Craig Mautner4e5b67e2014-02-07 15:30:03 -0800152 final IIntentSender iIntentSender = pendingIntent.getTarget();
Craig Mautnerdf88d732014-01-27 09:21:32 -0800153 if (mSurface != null) {
Craig Mautner4e5b67e2014-02-07 15:30:03 -0800154 startActivityIntentSender(iIntentSender);
155 } else {
156 mQueuedPendingIntent = iIntentSender;
157 mQueuedIntent = null;
Craig Mautnerdf88d732014-01-27 09:21:32 -0800158 }
159 }
160
161 private void attachToSurfaceWhenReady() {
162 final SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
163 if (mActivityContainer == null || surfaceTexture == null || mSurface != null) {
164 // Either not ready to attach, or already attached.
165 return;
166 }
167
Craig Mautner4504de52013-12-20 09:06:56 -0800168 WindowManager wm = (WindowManager)mActivity.getSystemService(Context.WINDOW_SERVICE);
169 DisplayMetrics metrics = new DisplayMetrics();
170 wm.getDefaultDisplay().getMetrics(metrics);
171
Craig Mautner34b73df2014-01-12 21:11:08 -0800172 mSurface = new Surface(surfaceTexture);
Craig Mautner4504de52013-12-20 09:06:56 -0800173 try {
Craig Mautnerdf88d732014-01-27 09:21:32 -0800174 mActivityContainer.attachToSurface(mSurface, mWidth, mHeight, metrics.densityDpi);
Craig Mautner4504de52013-12-20 09:06:56 -0800175 } catch (RemoteException e) {
Craig Mautner34b73df2014-01-12 21:11:08 -0800176 mSurface.release();
177 mSurface = null;
Craig Mautner4504de52013-12-20 09:06:56 -0800178 throw new IllegalStateException(
179 "ActivityView: Unable to create ActivityContainer. " + e);
180 }
Craig Mautner4e5b67e2014-02-07 15:30:03 -0800181
182 if (mQueuedIntent != null) {
183 startActivity(mQueuedIntent);
184 mQueuedIntent = null;
185 } else if (mQueuedPendingIntent != null) {
186 startActivityIntentSender(mQueuedPendingIntent);
187 mQueuedPendingIntent = null;
188 }
Craig Mautner4504de52013-12-20 09:06:56 -0800189 }
190
Craig Mautnerdf88d732014-01-27 09:21:32 -0800191 private void detach() {
192 if (mSurface != null) {
Craig Mautner34b73df2014-01-12 21:11:08 -0800193 try {
194 mActivityContainer.detachFromDisplay();
195 } catch (RemoteException e) {
196 }
Craig Mautner34b73df2014-01-12 21:11:08 -0800197 mSurface.release();
198 mSurface = null;
199 }
Craig Mautner34b73df2014-01-12 21:11:08 -0800200 }
201
Craig Mautner4504de52013-12-20 09:06:56 -0800202 private class ActivityViewSurfaceTextureListener implements SurfaceTextureListener {
203 @Override
204 public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width,
205 int height) {
206 mWidth = width;
207 mHeight = height;
208 if (mActivityContainer != null) {
Craig Mautnerdf88d732014-01-27 09:21:32 -0800209 attachToSurfaceWhenReady();
Craig Mautner4504de52013-12-20 09:06:56 -0800210 }
211 }
212
213 @Override
214 public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width,
215 int height) {
Craig Mautner34b73df2014-01-12 21:11:08 -0800216 Log.d(TAG, "onSurfaceTextureSizeChanged: w=" + width + " h=" + height);
Craig Mautner4504de52013-12-20 09:06:56 -0800217 }
218
219 @Override
220 public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
Craig Mautner34b73df2014-01-12 21:11:08 -0800221 Log.d(TAG, "onSurfaceTextureDestroyed");
Craig Mautnerdf88d732014-01-27 09:21:32 -0800222 detach();
Craig Mautner34b73df2014-01-12 21:11:08 -0800223 return true;
Craig Mautner4504de52013-12-20 09:06:56 -0800224 }
225
226 @Override
227 public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
Craig Mautner34b73df2014-01-12 21:11:08 -0800228// Log.d(TAG, "onSurfaceTextureUpdated");
Craig Mautner4504de52013-12-20 09:06:56 -0800229 }
230
231 }
232}