Home | History | Annotate | Download | only in projection
      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 
     68     @Override
     69     public void onCreate(Bundle savedInstanceState) {
     70         super.onCreate(savedInstanceState);
     71         setContentView(R.layout.media_projection);
     72 
     73         DisplayMetrics metrics = new DisplayMetrics();
     74         getWindowManager().getDefaultDisplay().getMetrics(metrics);
     75         mScreenDensity = metrics.densityDpi;
     76 
     77         mSurfaceView = (SurfaceView) findViewById(R.id.surface);
     78         mSurface = mSurfaceView.getHolder().getSurface();
     79         mProjectionManager =
     80             (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
     81 
     82         ArrayAdapter<Resolution> arrayAdapter = new ArrayAdapter<Resolution>(
     83                 this, android.R.layout.simple_list_item_1, RESOLUTIONS);
     84         Spinner s = (Spinner) findViewById(R.id.spinner);
     85         s.setAdapter(arrayAdapter);
     86         s.setOnItemSelectedListener(new ResolutionSelector());
     87         s.setSelection(0);
     88     }
     89 
     90     @Override
     91     public void onDestroy() {
     92         super.onDestroy();
     93         if (mMediaProjection != null) {
     94             mMediaProjection.stop();
     95             mMediaProjection = null;
     96         }
     97     }
     98 
     99     @Override
    100     public void onActivityResult(int requestCode, int resultCode, Intent data) {
    101         if (requestCode != PERMISSION_CODE) {
    102             Log.e(TAG, "Unknown request code: " + requestCode);
    103             return;
    104         }
    105         if (resultCode != RESULT_OK) {
    106             Toast.makeText(this,
    107                     "User denied screen sharing permission", Toast.LENGTH_SHORT).show();
    108             return;
    109         }
    110         mMediaProjection = mProjectionManager.getMediaProjection(resultCode, data);
    111         mVirtualDisplay = createVirtualDisplay();
    112     }
    113 
    114     public void onToggleScreenShare(View view) {
    115         if (((ToggleButton) view).isChecked()) {
    116             shareScreen();
    117         } else {
    118             stopScreenSharing();
    119         }
    120     }
    121 
    122     private void shareScreen() {
    123         mScreenSharing = true;
    124         if (mSurface == null) {
    125             return;
    126         }
    127         if (mMediaProjection == null) {
    128             startActivityForResult(mProjectionManager.createScreenCaptureIntent(),
    129                     PERMISSION_CODE);
    130             return;
    131         }
    132         mVirtualDisplay = createVirtualDisplay();
    133     }
    134 
    135     private void stopScreenSharing() {
    136         mScreenSharing = false;
    137         if (mVirtualDisplay == null) {
    138             return;
    139         }
    140         mVirtualDisplay.release();
    141     }
    142 
    143     private VirtualDisplay createVirtualDisplay() {
    144         return mMediaProjection.createVirtualDisplay("ScreenSharingDemo",
    145                 mDisplayWidth, mDisplayHeight, mScreenDensity,
    146                 DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
    147                 mSurface, null /*Callbacks*/, null /*Handler*/);
    148     }
    149 
    150     private void resizeVirtualDisplay() {
    151         if (mVirtualDisplay == null) {
    152             return;
    153         }
    154         mVirtualDisplay.resize(mDisplayWidth, mDisplayHeight, mScreenDensity);
    155     }
    156 
    157     private class ResolutionSelector implements Spinner.OnItemSelectedListener {
    158         @Override
    159         public void onItemSelected(AdapterView<?> parent, View v, int pos, long id) {
    160             Resolution r = (Resolution) parent.getItemAtPosition(pos);
    161             ViewGroup.LayoutParams lp = mSurfaceView.getLayoutParams();
    162             if (getResources().getConfiguration().orientation
    163                     == Configuration.ORIENTATION_LANDSCAPE) {
    164                 mDisplayHeight = r.y;
    165                 mDisplayWidth = r.x;
    166             } else {
    167                 mDisplayHeight = r.x;
    168                 mDisplayWidth = r.y;
    169             }
    170             lp.height = mDisplayHeight;
    171             lp.width = mDisplayWidth;
    172             mSurfaceView.setLayoutParams(lp);
    173         }
    174 
    175         @Override
    176         public void onNothingSelected(AdapterView<?> parent) { /* Ignore */ }
    177     }
    178 
    179     private class MediaProjectionCallback extends MediaProjection.Callback {
    180         @Override
    181         public void onStop() {
    182             mMediaProjection = null;
    183             stopScreenSharing();
    184         }
    185     }
    186 
    187     private class SurfaceCallbacks implements SurfaceHolder.Callback {
    188         @Override
    189         public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    190             mDisplayWidth = width;
    191             mDisplayHeight = height;
    192             resizeVirtualDisplay();
    193         }
    194 
    195         @Override
    196         public void surfaceCreated(SurfaceHolder holder) {
    197             mSurface = holder.getSurface();
    198             if (mScreenSharing) {
    199                 shareScreen();
    200             }
    201         }
    202 
    203         @Override
    204         public void surfaceDestroyed(SurfaceHolder holder) {
    205             if (!mScreenSharing) {
    206                 stopScreenSharing();
    207             }
    208         }
    209     }
    210 
    211     private static class Resolution {
    212         int x;
    213         int y;
    214 
    215         public Resolution(int x, int y) {
    216             this.x = x;
    217             this.y = y;
    218         }
    219 
    220         @Override
    221         public String toString() {
    222             return x + "x" + y;
    223         }
    224     }
    225 }
    226