| /* |
| * Copyright (C) 2014 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.example.android.apis.media.projection; |
| |
| import com.example.android.apis.R; |
| |
| import android.app.Activity; |
| import android.content.Context; |
| import android.content.Intent; |
| import android.content.res.Configuration; |
| import android.hardware.display.DisplayManager; |
| import android.hardware.display.VirtualDisplay; |
| import android.media.projection.MediaProjection; |
| import android.media.projection.MediaProjectionManager; |
| import android.os.Bundle; |
| import android.util.DisplayMetrics; |
| import android.util.Log; |
| import android.view.Surface; |
| import android.view.SurfaceHolder; |
| import android.view.SurfaceView; |
| import android.view.View; |
| import android.view.ViewGroup; |
| import android.widget.AdapterView; |
| import android.widget.ArrayAdapter; |
| import android.widget.Spinner; |
| import android.widget.Toast; |
| import android.widget.ToggleButton; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| public class MediaProjectionDemo extends Activity { |
| private static final String TAG = "MediaProjectionDemo"; |
| private static final int PERMISSION_CODE = 1; |
| private static final List<Resolution> RESOLUTIONS = new ArrayList<Resolution>() {{ |
| add(new Resolution(640,360)); |
| add(new Resolution(960,540)); |
| add(new Resolution(1366,768)); |
| add(new Resolution(1600,900)); |
| }}; |
| |
| private int mScreenDensity; |
| private MediaProjectionManager mProjectionManager; |
| |
| private int mDisplayWidth; |
| private int mDisplayHeight; |
| private boolean mScreenSharing; |
| |
| private MediaProjection mMediaProjection; |
| private VirtualDisplay mVirtualDisplay; |
| private Surface mSurface; |
| private SurfaceView mSurfaceView; |
| |
| @Override |
| public void onCreate(Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| setContentView(R.layout.media_projection); |
| |
| DisplayMetrics metrics = new DisplayMetrics(); |
| getWindowManager().getDefaultDisplay().getMetrics(metrics); |
| mScreenDensity = metrics.densityDpi; |
| |
| mSurfaceView = (SurfaceView) findViewById(R.id.surface); |
| mSurface = mSurfaceView.getHolder().getSurface(); |
| mProjectionManager = |
| (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE); |
| |
| ArrayAdapter<Resolution> arrayAdapter = new ArrayAdapter<Resolution>( |
| this, android.R.layout.simple_list_item_1, RESOLUTIONS); |
| Spinner s = (Spinner) findViewById(R.id.spinner); |
| s.setAdapter(arrayAdapter); |
| s.setOnItemSelectedListener(new ResolutionSelector()); |
| s.setSelection(0); |
| } |
| |
| @Override |
| public void onDestroy() { |
| super.onDestroy(); |
| if (mMediaProjection != null) { |
| mMediaProjection.stop(); |
| mMediaProjection = null; |
| } |
| } |
| |
| @Override |
| public void onActivityResult(int requestCode, int resultCode, Intent data) { |
| if (requestCode != PERMISSION_CODE) { |
| Log.e(TAG, "Unknown request code: " + requestCode); |
| return; |
| } |
| if (resultCode != RESULT_OK) { |
| Toast.makeText(this, |
| "User denied screen sharing permission", Toast.LENGTH_SHORT).show(); |
| return; |
| } |
| mMediaProjection = mProjectionManager.getMediaProjection(resultCode, data); |
| mVirtualDisplay = createVirtualDisplay(); |
| } |
| |
| public void onToggleScreenShare(View view) { |
| if (((ToggleButton) view).isChecked()) { |
| shareScreen(); |
| } else { |
| stopScreenSharing(); |
| } |
| } |
| |
| private void shareScreen() { |
| mScreenSharing = true; |
| if (mSurface == null) { |
| return; |
| } |
| if (mMediaProjection == null) { |
| startActivityForResult(mProjectionManager.createScreenCaptureIntent(), |
| PERMISSION_CODE); |
| return; |
| } |
| mVirtualDisplay = createVirtualDisplay(); |
| } |
| |
| private void stopScreenSharing() { |
| mScreenSharing = false; |
| if (mVirtualDisplay == null) { |
| return; |
| } |
| mVirtualDisplay.release(); |
| } |
| |
| private VirtualDisplay createVirtualDisplay() { |
| return mMediaProjection.createVirtualDisplay("ScreenSharingDemo", |
| mDisplayWidth, mDisplayHeight, mScreenDensity, |
| DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, |
| mSurface, null /*Callbacks*/, null /*Handler*/); |
| } |
| |
| private void resizeVirtualDisplay() { |
| if (mVirtualDisplay == null) { |
| return; |
| } |
| mVirtualDisplay.resize(mDisplayWidth, mDisplayHeight, mScreenDensity); |
| } |
| |
| private class ResolutionSelector implements Spinner.OnItemSelectedListener { |
| @Override |
| public void onItemSelected(AdapterView<?> parent, View v, int pos, long id) { |
| Resolution r = (Resolution) parent.getItemAtPosition(pos); |
| ViewGroup.LayoutParams lp = mSurfaceView.getLayoutParams(); |
| if (getResources().getConfiguration().orientation |
| == Configuration.ORIENTATION_LANDSCAPE) { |
| mDisplayHeight = r.y; |
| mDisplayWidth = r.x; |
| } else { |
| mDisplayHeight = r.x; |
| mDisplayWidth = r.y; |
| } |
| lp.height = mDisplayHeight; |
| lp.width = mDisplayWidth; |
| mSurfaceView.setLayoutParams(lp); |
| } |
| |
| @Override |
| public void onNothingSelected(AdapterView<?> parent) { /* Ignore */ } |
| } |
| |
| private class MediaProjectionCallback extends MediaProjection.Callback { |
| @Override |
| public void onStop() { |
| mMediaProjection = null; |
| stopScreenSharing(); |
| } |
| } |
| |
| private class SurfaceCallbacks implements SurfaceHolder.Callback { |
| @Override |
| public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { |
| mDisplayWidth = width; |
| mDisplayHeight = height; |
| resizeVirtualDisplay(); |
| } |
| |
| @Override |
| public void surfaceCreated(SurfaceHolder holder) { |
| mSurface = holder.getSurface(); |
| if (mScreenSharing) { |
| shareScreen(); |
| } |
| } |
| |
| @Override |
| public void surfaceDestroyed(SurfaceHolder holder) { |
| if (!mScreenSharing) { |
| stopScreenSharing(); |
| } |
| } |
| } |
| |
| private static class Resolution { |
| int x; |
| int y; |
| |
| public Resolution(int x, int y) { |
| this.x = x; |
| this.y = y; |
| } |
| |
| @Override |
| public String toString() { |
| return x + "x" + y; |
| } |
| } |
| } |