1 /* 2 * Copyright (C) 2019 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 package com.google.android.car.kitchensink.projection; 17 18 import android.car.CarProjectionManager; 19 import android.car.CarProjectionManager.ProjectionStatusListener; 20 import android.car.projection.ProjectionStatus; 21 import android.os.Bundle; 22 import android.view.LayoutInflater; 23 import android.view.View; 24 import android.view.ViewGroup; 25 import android.widget.LinearLayout; 26 import android.widget.TextView; 27 28 import androidx.fragment.app.Fragment; 29 30 import com.google.android.car.kitchensink.KitchenSinkActivity; 31 import com.google.android.car.kitchensink.R; 32 import com.google.common.collect.ImmutableMap; 33 34 import java.util.List; 35 36 /** 37 * Reports information about the current projection status. 38 */ 39 public class ProjectionFragment extends Fragment { 40 private KitchenSinkActivity mActivity; 41 private CarProjectionManager mCarProjectionManager; 42 43 private TextView mCurrentProjectionStatus; 44 private TextView mCurrentProjectionPackage; 45 private LinearLayout mCurrentProjectionDetails; 46 47 private static final ImmutableMap<Integer, String> STATE_TO_STRING = ImmutableMap.of( 48 ProjectionStatus.PROJECTION_STATE_INACTIVE, "Inactive", 49 ProjectionStatus.PROJECTION_STATE_READY_TO_PROJECT, "Ready to project", 50 ProjectionStatus.PROJECTION_STATE_ACTIVE_FOREGROUND, "Foreground", 51 ProjectionStatus.PROJECTION_STATE_ACTIVE_BACKGROUND, "Background"); 52 53 private static final ImmutableMap<Integer, String> TRANSPORT_TO_STRING = ImmutableMap.of( 54 ProjectionStatus.PROJECTION_TRANSPORT_NONE, "None", 55 ProjectionStatus.PROJECTION_TRANSPORT_USB, "USB", 56 ProjectionStatus.PROJECTION_TRANSPORT_WIFI, "WiFi"); 57 58 private class KitchenSinkProjectionStatusListener implements ProjectionStatusListener { 59 @Override onProjectionStatusChanged( int state, String packageName, List<ProjectionStatus> details)60 public void onProjectionStatusChanged( 61 int state, 62 String packageName, 63 List<ProjectionStatus> details) { 64 mCurrentProjectionStatus.setText(STATE_TO_STRING.get(state)); 65 mCurrentProjectionPackage.setText(packageName); 66 mCurrentProjectionDetails.removeAllViews(); 67 for (ProjectionStatus detail : details) { 68 LinearLayout detailLayout = 69 (LinearLayout) 70 getLayoutInflater() 71 .inflate(R.layout.projection_status_details, null); 72 73 TextView detailPackage = detailLayout.findViewById(R.id.projection_detail_package); 74 detailPackage.setText(detail.getPackageName()); 75 76 TextView detailState = detailLayout.findViewById(R.id.projection_detail_state); 77 detailState.setText(STATE_TO_STRING.get(detail.getState())); 78 79 TextView detailTransport = 80 detailLayout.findViewById(R.id.projection_detail_transport); 81 detailTransport.setText(TRANSPORT_TO_STRING.get(detail.getTransport())); 82 83 for (ProjectionStatus.MobileDevice device : detail.getConnectedMobileDevices()) { 84 LinearLayout deviceLayout = 85 (LinearLayout) 86 getLayoutInflater() 87 .inflate(R.layout.projection_status_device, null); 88 89 TextView deviceId = deviceLayout.findViewById(R.id.projection_device_id); 90 deviceId.setText(String.valueOf(device.getId())); 91 92 TextView deviceName = deviceLayout.findViewById(R.id.projection_device_name); 93 deviceName.setText(device.getName()); 94 95 LinearLayout deviceTransports = 96 deviceLayout.findViewById(R.id.projection_device_transports); 97 for (Integer transport : device.getAvailableTransports()) { 98 TextView transportView = new TextView(mActivity); 99 transportView.setText(TRANSPORT_TO_STRING.get(transport)); 100 101 deviceTransports.addView(transportView); 102 } 103 104 TextView deviceProjecting = 105 deviceLayout.findViewById(R.id.projection_device_projecting); 106 deviceProjecting.setText(String.valueOf(device.isProjecting())); 107 108 detailLayout.addView(deviceLayout); 109 } 110 mCurrentProjectionDetails.addView(detailLayout); 111 } 112 } 113 } 114 115 private final KitchenSinkProjectionStatusListener mProjectionListener = 116 new KitchenSinkProjectionStatusListener(); 117 118 @Override onCreate(Bundle savedInstanceState)119 public void onCreate(Bundle savedInstanceState) { 120 mActivity = (KitchenSinkActivity) getActivity(); 121 mCarProjectionManager = mActivity.getProjectionManager(); 122 super.onCreate(savedInstanceState); 123 } 124 125 @Override onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)126 public View onCreateView( 127 LayoutInflater inflater, 128 ViewGroup container, 129 Bundle savedInstanceState) { 130 View layout = inflater.inflate(R.layout.projection_status, container, false); 131 132 mCurrentProjectionStatus = (TextView) layout.findViewById(R.id.current_projection_status); 133 mCurrentProjectionPackage = (TextView) layout.findViewById(R.id.current_projection_package); 134 mCurrentProjectionDetails = 135 (LinearLayout) layout.findViewById(R.id.current_projection_details); 136 137 return layout; 138 } 139 140 @Override onStart()141 public void onStart() { 142 mCarProjectionManager.registerProjectionStatusListener(mProjectionListener); 143 super.onStart(); 144 } 145 146 @Override onStop()147 public void onStop() { 148 mCarProjectionManager.unregisterProjectionStatusListener(mProjectionListener); 149 super.onStop(); 150 } 151 } 152