• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Copyright (C) 2014 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  
17  package com.example.android.apis.media.projection;
18  
19  import com.example.android.apis.R;
20  
21  import android.app.Activity;
22  import android.content.Context;
23  import android.content.Intent;
24  import android.content.res.Configuration;
25  import android.hardware.display.DisplayManager;
26  import android.hardware.display.VirtualDisplay;
27  import android.media.projection.MediaProjection;
28  import android.media.projection.MediaProjectionManager;
29  import android.os.Bundle;
30  import android.util.DisplayMetrics;
31  import android.util.Log;
32  import android.view.Surface;
33  import android.view.SurfaceHolder;
34  import android.view.SurfaceView;
35  import android.view.View;
36  import android.view.ViewGroup;
37  import android.widget.AdapterView;
38  import android.widget.ArrayAdapter;
39  import android.widget.Spinner;
40  import android.widget.Toast;
41  import android.widget.ToggleButton;
42  
43  import java.util.ArrayList;
44  import java.util.List;
45  
46  public class MediaProjectionDemo extends Activity {
47      private static final String TAG = "MediaProjectionDemo";
48      private static final int PERMISSION_CODE = 1;
49      private static final List<Resolution> RESOLUTIONS = new ArrayList<Resolution>() {{
50          add(new Resolution(640,360));
51          add(new Resolution(960,540));
52          add(new Resolution(1366,768));
53          add(new Resolution(1600,900));
54      }};
55  
56      private int mScreenDensity;
57      private MediaProjectionManager mProjectionManager;
58  
59      private int mDisplayWidth;
60      private int mDisplayHeight;
61      private boolean mScreenSharing;
62  
63      private MediaProjection mMediaProjection;
64      private VirtualDisplay mVirtualDisplay;
65      private Surface mSurface;
66      private SurfaceView mSurfaceView;
67      private ToggleButton mToggle;
68  
69      @Override
onCreate(Bundle savedInstanceState)70      public void onCreate(Bundle savedInstanceState) {
71          super.onCreate(savedInstanceState);
72          setContentView(R.layout.media_projection);
73  
74          DisplayMetrics metrics = new DisplayMetrics();
75          getWindowManager().getDefaultDisplay().getMetrics(metrics);
76          mScreenDensity = metrics.densityDpi;
77  
78          mSurfaceView = (SurfaceView) findViewById(R.id.surface);
79          mSurface = mSurfaceView.getHolder().getSurface();
80          mProjectionManager =
81              (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
82  
83          ArrayAdapter<Resolution> arrayAdapter = new ArrayAdapter<Resolution>(
84                  this, android.R.layout.simple_list_item_1, RESOLUTIONS);
85          Spinner s = (Spinner) findViewById(R.id.spinner);
86          s.setAdapter(arrayAdapter);
87          s.setOnItemSelectedListener(new ResolutionSelector());
88          s.setSelection(0);
89  
90          mToggle = (ToggleButton) findViewById(R.id.screen_sharing_toggle);
91          mToggle.setSaveEnabled(false);
92      }
93  
94      @Override
onStop()95      protected void onStop() {
96          stopScreenSharing();
97          super.onStop();
98      }
99  
100      @Override
onDestroy()101      public void onDestroy() {
102          super.onDestroy();
103          if (mMediaProjection != null) {
104              mMediaProjection.stop();
105              mMediaProjection = null;
106          }
107      }
108  
109      @Override
onActivityResult(int requestCode, int resultCode, Intent data)110      public void onActivityResult(int requestCode, int resultCode, Intent data) {
111          if (requestCode != PERMISSION_CODE) {
112              Log.e(TAG, "Unknown request code: " + requestCode);
113              return;
114          }
115          if (resultCode != RESULT_OK) {
116              Toast.makeText(this,
117                      "User denied screen sharing permission", Toast.LENGTH_SHORT).show();
118              return;
119          }
120          mMediaProjection = mProjectionManager.getMediaProjection(resultCode, data);
121          mMediaProjection.registerCallback(new MediaProjectionCallback(), null);
122          mVirtualDisplay = createVirtualDisplay();
123      }
124  
onToggleScreenShare(View view)125      public void onToggleScreenShare(View view) {
126          if (((ToggleButton) view).isChecked()) {
127              shareScreen();
128          } else {
129              stopScreenSharing();
130          }
131      }
132  
shareScreen()133      private void shareScreen() {
134          mScreenSharing = true;
135          if (mSurface == null) {
136              return;
137          }
138          if (mMediaProjection == null) {
139              startActivityForResult(mProjectionManager.createScreenCaptureIntent(),
140                      PERMISSION_CODE);
141              return;
142          }
143          mVirtualDisplay = createVirtualDisplay();
144      }
145  
stopScreenSharing()146      private void stopScreenSharing() {
147          if (mToggle.isChecked()) {
148              mToggle.setChecked(false);
149          }
150  
151          mScreenSharing = false;
152          if (mVirtualDisplay != null) {
153              mVirtualDisplay.release();
154              mVirtualDisplay = null;
155          }
156      }
157  
createVirtualDisplay()158      private VirtualDisplay createVirtualDisplay() {
159          return mMediaProjection.createVirtualDisplay("ScreenSharingDemo",
160                  mDisplayWidth, mDisplayHeight, mScreenDensity,
161                  DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
162                  mSurface, null /*Callbacks*/, null /*Handler*/);
163      }
164  
resizeVirtualDisplay()165      private void resizeVirtualDisplay() {
166          if (mVirtualDisplay == null) {
167              return;
168          }
169          mVirtualDisplay.resize(mDisplayWidth, mDisplayHeight, mScreenDensity);
170      }
171  
172      private class ResolutionSelector implements Spinner.OnItemSelectedListener {
173          @Override
onItemSelected(AdapterView<?> parent, View v, int pos, long id)174          public void onItemSelected(AdapterView<?> parent, View v, int pos, long id) {
175              Resolution r = (Resolution) parent.getItemAtPosition(pos);
176              ViewGroup.LayoutParams lp = mSurfaceView.getLayoutParams();
177              if (getResources().getConfiguration().orientation
178                      == Configuration.ORIENTATION_LANDSCAPE) {
179                  mDisplayHeight = r.y;
180                  mDisplayWidth = r.x;
181              } else {
182                  mDisplayHeight = r.x;
183                  mDisplayWidth = r.y;
184              }
185              lp.height = mDisplayHeight;
186              lp.width = mDisplayWidth;
187              mSurfaceView.setLayoutParams(lp);
188          }
189  
190          @Override
onNothingSelected(AdapterView<?> parent)191          public void onNothingSelected(AdapterView<?> parent) { /* Ignore */ }
192      }
193  
194      private class MediaProjectionCallback extends MediaProjection.Callback {
195          @Override
onStop()196          public void onStop() {
197              mMediaProjection = null;
198              stopScreenSharing();
199          }
200      }
201  
202      private class SurfaceCallbacks implements SurfaceHolder.Callback {
203          @Override
surfaceChanged(SurfaceHolder holder, int format, int width, int height)204          public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
205              mDisplayWidth = width;
206              mDisplayHeight = height;
207              resizeVirtualDisplay();
208          }
209  
210          @Override
surfaceCreated(SurfaceHolder holder)211          public void surfaceCreated(SurfaceHolder holder) {
212              mSurface = holder.getSurface();
213              if (mScreenSharing) {
214                  shareScreen();
215              }
216          }
217  
218          @Override
surfaceDestroyed(SurfaceHolder holder)219          public void surfaceDestroyed(SurfaceHolder holder) {
220              if (!mScreenSharing) {
221                  stopScreenSharing();
222              }
223          }
224      }
225  
226      private static class Resolution {
227          int x;
228          int y;
229  
Resolution(int x, int y)230          public Resolution(int x, int y) {
231              this.x = x;
232              this.y = y;
233          }
234  
235          @Override
toString()236          public String toString() {
237              return x + "x" + y;
238          }
239      }
240  }
241