• 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     }
92 
93     @Override
onDestroy()94     public void onDestroy() {
95         super.onDestroy();
96         if (mMediaProjection != null) {
97             mMediaProjection.stop();
98             mMediaProjection = null;
99         }
100     }
101 
102     @Override
onActivityResult(int requestCode, int resultCode, Intent data)103     public void onActivityResult(int requestCode, int resultCode, Intent data) {
104         if (requestCode != PERMISSION_CODE) {
105             Log.e(TAG, "Unknown request code: " + requestCode);
106             return;
107         }
108         if (resultCode != RESULT_OK) {
109             Toast.makeText(this,
110                     "User denied screen sharing permission", Toast.LENGTH_SHORT).show();
111             return;
112         }
113         mMediaProjection = mProjectionManager.getMediaProjection(resultCode, data);
114         mMediaProjection.registerCallback(new MediaProjectionCallback(), null);
115         mVirtualDisplay = createVirtualDisplay();
116     }
117 
onToggleScreenShare(View view)118     public void onToggleScreenShare(View view) {
119         if (((ToggleButton) view).isChecked()) {
120             shareScreen();
121         } else {
122             stopScreenSharing();
123         }
124     }
125 
shareScreen()126     private void shareScreen() {
127         mScreenSharing = true;
128         if (mSurface == null) {
129             return;
130         }
131         if (mMediaProjection == null) {
132             startActivityForResult(mProjectionManager.createScreenCaptureIntent(),
133                     PERMISSION_CODE);
134             return;
135         }
136         mVirtualDisplay = createVirtualDisplay();
137     }
138 
stopScreenSharing()139     private void stopScreenSharing() {
140         if (mToggle.isChecked()) {
141             mToggle.setChecked(false);
142         }
143         mScreenSharing = false;
144         if (mVirtualDisplay != null) {
145             mVirtualDisplay.release();
146             mVirtualDisplay = null;
147         }
148     }
149 
createVirtualDisplay()150     private VirtualDisplay createVirtualDisplay() {
151         return mMediaProjection.createVirtualDisplay("ScreenSharingDemo",
152                 mDisplayWidth, mDisplayHeight, mScreenDensity,
153                 DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
154                 mSurface, null /*Callbacks*/, null /*Handler*/);
155     }
156 
resizeVirtualDisplay()157     private void resizeVirtualDisplay() {
158         if (mVirtualDisplay == null) {
159             return;
160         }
161         mVirtualDisplay.resize(mDisplayWidth, mDisplayHeight, mScreenDensity);
162     }
163 
164     private class ResolutionSelector implements Spinner.OnItemSelectedListener {
165         @Override
onItemSelected(AdapterView<?> parent, View v, int pos, long id)166         public void onItemSelected(AdapterView<?> parent, View v, int pos, long id) {
167             Resolution r = (Resolution) parent.getItemAtPosition(pos);
168             ViewGroup.LayoutParams lp = mSurfaceView.getLayoutParams();
169             if (getResources().getConfiguration().orientation
170                     == Configuration.ORIENTATION_LANDSCAPE) {
171                 mDisplayHeight = r.y;
172                 mDisplayWidth = r.x;
173             } else {
174                 mDisplayHeight = r.x;
175                 mDisplayWidth = r.y;
176             }
177             lp.height = mDisplayHeight;
178             lp.width = mDisplayWidth;
179             mSurfaceView.setLayoutParams(lp);
180         }
181 
182         @Override
onNothingSelected(AdapterView<?> parent)183         public void onNothingSelected(AdapterView<?> parent) { /* Ignore */ }
184     }
185 
186     private class MediaProjectionCallback extends MediaProjection.Callback {
187         @Override
onStop()188         public void onStop() {
189             mMediaProjection = null;
190             stopScreenSharing();
191         }
192     }
193 
194     private class SurfaceCallbacks implements SurfaceHolder.Callback {
195         @Override
surfaceChanged(SurfaceHolder holder, int format, int width, int height)196         public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
197             mDisplayWidth = width;
198             mDisplayHeight = height;
199             resizeVirtualDisplay();
200         }
201 
202         @Override
surfaceCreated(SurfaceHolder holder)203         public void surfaceCreated(SurfaceHolder holder) {
204             mSurface = holder.getSurface();
205             if (mScreenSharing) {
206                 shareScreen();
207             }
208         }
209 
210         @Override
surfaceDestroyed(SurfaceHolder holder)211         public void surfaceDestroyed(SurfaceHolder holder) {
212             if (!mScreenSharing) {
213                 stopScreenSharing();
214             }
215         }
216     }
217 
218     private static class Resolution {
219         int x;
220         int y;
221 
Resolution(int x, int y)222         public Resolution(int x, int y) {
223             this.x = x;
224             this.y = y;
225         }
226 
227         @Override
toString()228         public String toString() {
229             return x + "x" + y;
230         }
231     }
232 }
233