1b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv/* 2b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv * Copyright (C) 2016 The Android Open Source Project 3b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv * 4b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv * Licensed under the Apache License, Version 2.0 (the "License"); 5b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv * you may not use this file except in compliance with the License. 6b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv * You may obtain a copy of the License at 7b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv * 8b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv * http://www.apache.org/licenses/LICENSE-2.0 9b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv * 10b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv * Unless required by applicable law or agreed to in writing, software 11b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv * distributed under the License is distributed on an "AS IS" BASIS, 12b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv * See the License for the specific language governing permissions and 14b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv * limitations under the License. 15b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv */ 16b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkivpackage com.google.android.car.kitchensink.setting; 17b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv 18b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkivimport android.annotation.Nullable; 19b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkivimport android.app.Activity; 20b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkivimport android.content.ComponentName; 21b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkivimport android.content.Context; 22b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkivimport android.content.Intent; 23b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkivimport android.content.pm.ApplicationInfo; 24b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkivimport android.content.pm.PackageManager; 25b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkivimport android.content.pm.PackageManager.NameNotFoundException; 26b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkivimport android.hardware.usb.UsbDevice; 27b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkivimport android.hardware.usb.UsbManager; 28b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkivimport android.os.Bundle; 29b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkivimport android.util.Log; 30b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkivimport android.view.View; 31b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkivimport android.view.ViewGroup; 32b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkivimport android.widget.AdapterView; 33b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkivimport android.widget.ArrayAdapter; 34b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkivimport android.widget.ImageView; 35b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkivimport android.widget.LinearLayout; 36b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkivimport android.widget.ListView; 37b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkivimport android.widget.TextView; 38b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv 39b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkivimport com.google.android.car.kitchensink.R; 40b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkivimport com.google.android.car.kitchensink.setting.usb.UsbDeviceSettings; 41b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkivimport com.google.android.car.kitchensink.setting.usb.UsbHostController; 42b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv 43b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkivimport java.util.List; 44b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv 45b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv/** 46b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv * Activity to handle USB device attached. 47b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv * <p> 48b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv * When user plugs in USB device: 49b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv * a) Device was used before and user selected handler for it. 50b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv * In this case handler will be launched. 51b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv * b) Device has not handler assigned. In this case supported handlers will be captured, 52b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv * and user will be presented with choice to assign default handler. 53b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv * After that handler will be lauched. 54b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv */ 55b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkivpublic class UsbHostManagementActivity extends Activity 56b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv implements UsbHostController.UsbHostControllerCallbacks { 57b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv private static final String TAG = UsbHostManagementActivity.class.getSimpleName(); 58b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv private static final boolean LOCAL_LOGD = true; 59b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv private static final boolean LOCAL_LOGV = true; 60b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv 61b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv private HandlersAdapter mListAdapter; 62b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv private ListView mHandlersList; 63b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv private LinearLayout mProgressInfo; 64b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv private UsbHostController mController; 65b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv private PackageManager mPackageManager; 66b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv 67b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv private final AdapterView.OnItemClickListener mHandlerClickListener = 68b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv new AdapterView.OnItemClickListener() { 69b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv @Override 70b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv public void onItemClick(AdapterView<?> parent, final View view, int position, long id) { 71b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv UsbDeviceSettings settings = (UsbDeviceSettings) parent.getItemAtPosition(position); 72b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv mController.applyDeviceSettings(settings); 73b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv } 74b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv }; 75b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv 76b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv @Override 77b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv public void onCreate(Bundle savedInstanceState) { 78b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv super.onCreate(savedInstanceState); 79b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv setContentView(R.layout.usb_host); 80b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv mHandlersList = (ListView) findViewById(R.id.usb_handlers_list); 81b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv mProgressInfo = (LinearLayout) findViewById(R.id.usb_handlers_progress); 82b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv mListAdapter = new HandlersAdapter(this); 83b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv mHandlersList.setAdapter(mListAdapter); 84b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv mHandlersList.setOnItemClickListener(mHandlerClickListener); 85b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv mController = new UsbHostController(this, this); 86b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv mPackageManager = getPackageManager(); 87b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv } 88b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv 89b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv @Override 90b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv public void onDestroy() { 91b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv super.onDestroy(); 92b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv mController.release(); 93b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv } 94b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv 95b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv @Override 96b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv public void onResume() { 97b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv super.onResume(); 98b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv UsbDevice connectedDevice = getDevice(); 99b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv if (connectedDevice != null) { 100b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv mController.processDevice(connectedDevice); 101b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv } else { 102b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv finish(); 103b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv } 104b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv } 105b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv 106b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv @Override 107b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv public void shutdown() { 108b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv runOnUiThread(new Runnable() { 109b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv @Override 110b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv public void run() { 111b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv finish(); 112b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv } 113b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv }); 114b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv } 115b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv 116b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv @Override 117b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv public void processingStateChanged(final boolean processing) { 118b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv runOnUiThread(new Runnable() { 119b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv @Override 120b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv public void run() { 121b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv mProgressInfo.setVisibility(processing ? View.VISIBLE : View.GONE); 122b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv } 123b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv }); 124b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv } 125b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv 126b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv @Override 127b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv public void titleChanged(String title) { 128b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv runOnUiThread(new Runnable() { 129b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv @Override 130b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv public void run() { 131b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv setTitle(title); 132b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv } 133b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv }); 134b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv } 135b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv 136b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv @Override 137b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv public void optionsUpdated(List<UsbDeviceSettings> options) { 138b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv runOnUiThread(new Runnable() { 139b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv @Override 140b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv public void run() { 141b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv mListAdapter.clear(); 142b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv mListAdapter.addAll(options); 143b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv } 144b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv }); 145b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv } 146b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv 147b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv 148b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv @Override 149b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv public void onNewIntent(Intent intent) { 150b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv super.onNewIntent(intent); 151b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv setIntent(intent); 152b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv } 153b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv 154b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv @Nullable 155b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv private UsbDevice getDevice() { 156b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv if (!UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(getIntent().getAction())) { 157b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv return null; 158b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv } 159b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv return (UsbDevice) getIntent().getParcelableExtra(UsbManager.EXTRA_DEVICE); 160b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv } 161b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv 162b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv private static Intent createDeviceAttachedIntent(UsbDevice device) { 163b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv Intent intent = new Intent(UsbManager.ACTION_USB_DEVICE_ATTACHED); 164b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv intent.putExtra(UsbManager.EXTRA_DEVICE, device); 165b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 166b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv return intent; 167b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv } 168b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv 169b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv private class HandlersAdapter extends ArrayAdapter<UsbDeviceSettings> { 170b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv class HandlerHolder { 171b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv public TextView mAppName; 172b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv public ImageView mAppIcon; 173b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv } 174b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv 175b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv HandlersAdapter(Context context) { 176b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv super(context, R.layout.usb_handler_row); 177b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv } 178b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv 179b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv @Override 180b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv public View getView(int position, View convertView, ViewGroup parent) { 181b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv View rowView = convertView; 182b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv if (rowView == null) { 183b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv rowView = getLayoutInflater().inflate(R.layout.usb_handler_row, null); 184b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv HandlerHolder holder = new HandlerHolder(); 185b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv holder.mAppName = (TextView) rowView.findViewById(R.id.usb_handler_title); 186b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv holder.mAppIcon = (ImageView) rowView.findViewById(R.id.usb_handler_icon); 187b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv rowView.setTag(holder); 188b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv } 189b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv 190b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv HandlerHolder holder = (HandlerHolder) rowView.getTag(); 191b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv ComponentName handler = getItem(position).getHandler(); 192b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv 193b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv try { 194b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv ApplicationInfo appInfo = 195b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv mPackageManager.getApplicationInfo(handler.getPackageName(), 0); 196b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv holder.mAppName.setText(appInfo.loadLabel(mPackageManager)); 197b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv holder.mAppIcon.setImageDrawable(appInfo.loadIcon(mPackageManager)); 198b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv } catch (NameNotFoundException e) { 199b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv Log.e(TAG, "Handling package not found: " + handler.getPackageName()); 200b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv holder.mAppName.setText(handler.flattenToShortString()); 201b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv holder.mAppIcon.setImageResource(android.R.color.transparent); 202b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv } 203b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv return rowView; 204b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv } 205b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv } 206b6af5c511a7f78e6bec870a5a0f660dabda45665Vitalii Tomkiv} 207