Home | History | Annotate | Download | only in kitchensink
      1 /*
      2  * Copyright (C) 2015 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.google.android.car.kitchensink;
     18 
     19 import android.car.hardware.hvac.CarHvacManager;
     20 import android.content.Intent;
     21 import android.content.pm.PackageManager;
     22 import android.os.Bundle;
     23 import android.support.car.Car;
     24 import android.support.car.CarAppFocusManager;
     25 import android.support.car.CarConnectionCallback;
     26 import android.support.car.CarNotConnectedException;
     27 import android.support.car.hardware.CarSensorManager;
     28 import android.support.v4.app.Fragment;
     29 import android.util.Log;
     30 import android.view.HapticFeedbackConstants;
     31 import android.view.View;
     32 import android.widget.ImageView;
     33 import android.widget.Toast;
     34 
     35 import com.android.car.app.CarDrawerActivity;
     36 import com.android.car.app.CarDrawerAdapter;
     37 import com.android.car.app.DrawerItemViewHolder;
     38 import com.google.android.car.kitchensink.assistant.CarAssistantFragment;
     39 import com.google.android.car.kitchensink.audio.AudioTestFragment;
     40 import com.google.android.car.kitchensink.bluetooth.BluetoothHeadsetFragment;
     41 import com.google.android.car.kitchensink.bluetooth.MapMceTestFragment;
     42 import com.google.android.car.kitchensink.cluster.InstrumentClusterFragment;
     43 import com.google.android.car.kitchensink.cube.CubesTestFragment;
     44 import com.google.android.car.kitchensink.diagnostic.DiagnosticTestFragment;
     45 import com.google.android.car.kitchensink.hvac.HvacTestFragment;
     46 import com.google.android.car.kitchensink.input.InputTestFragment;
     47 import com.google.android.car.kitchensink.job.JobSchedulerFragment;
     48 import com.google.android.car.kitchensink.orientation.OrientationTestFragment;
     49 import com.google.android.car.kitchensink.radio.RadioTestFragment;
     50 import com.google.android.car.kitchensink.sensor.SensorsTestFragment;
     51 import com.google.android.car.kitchensink.setting.CarServiceSettingsActivity;
     52 import com.google.android.car.kitchensink.touch.TouchTestFragment;
     53 import com.google.android.car.kitchensink.volume.VolumeTestFragment;
     54 import java.util.ArrayList;
     55 import java.util.List;
     56 
     57 public class KitchenSinkActivity extends CarDrawerActivity {
     58     private static final String TAG = "KitchenSinkActivity";
     59 
     60     private interface ClickHandler {
     61         void onClick();
     62     }
     63 
     64     private static abstract class MenuEntry implements ClickHandler {
     65         abstract String getText();
     66     }
     67 
     68     private final class OnClickMenuEntry extends MenuEntry {
     69         private final String mText;
     70         private final ClickHandler mClickHandler;
     71 
     72         OnClickMenuEntry(String text, ClickHandler clickHandler) {
     73             mText = text;
     74             mClickHandler = clickHandler;
     75         }
     76 
     77         @Override
     78         String getText() {
     79             return mText;
     80         }
     81 
     82         @Override
     83         public void onClick() {
     84             mClickHandler.onClick();
     85         }
     86     }
     87 
     88     private final class FragmentMenuEntry<T extends Fragment> extends MenuEntry {
     89         private final class FragmentClassOrInstance<T extends Fragment> {
     90             final Class<T> mClazz;
     91             T mFragment = null;
     92 
     93             FragmentClassOrInstance(Class<T> clazz) {
     94                 mClazz = clazz;
     95             }
     96 
     97             T getFragment() {
     98                 if (mFragment == null) {
     99                     try {
    100                         mFragment = mClazz.newInstance();
    101                     } catch (InstantiationException | IllegalAccessException e) {
    102                         Log.e(TAG, "unable to create fragment", e);
    103                     }
    104                 }
    105                 return mFragment;
    106             }
    107         }
    108 
    109         private final String mText;
    110         private final FragmentClassOrInstance<T> mFragment;
    111 
    112         FragmentMenuEntry(String text, Class<T> clazz) {
    113             mText = text;
    114             mFragment = new FragmentClassOrInstance<>(clazz);
    115         }
    116 
    117         @Override
    118         String getText() {
    119             return mText;
    120         }
    121 
    122         @Override
    123         public void onClick() {
    124             Fragment fragment = mFragment.getFragment();
    125             if (fragment != null) {
    126                 KitchenSinkActivity.this.showFragment(fragment);
    127             } else {
    128                 Log.e(TAG, "cannot show fragment for " + getText());
    129             }
    130         }
    131     }
    132 
    133     private final List<MenuEntry> mMenuEntries = new ArrayList<MenuEntry>() {
    134         {
    135             add("audio", AudioTestFragment.class);
    136             add("hvac", HvacTestFragment.class);
    137             add("job scheduler", JobSchedulerFragment.class);
    138             add("inst cluster", InstrumentClusterFragment.class);
    139             add("input test", InputTestFragment.class);
    140             add("radio", RadioTestFragment.class);
    141             add("assistant", CarAssistantFragment.class);
    142             add("sensors", SensorsTestFragment.class);
    143             add("diagnostic", DiagnosticTestFragment.class);
    144             add("volume test", VolumeTestFragment.class);
    145             add("touch test", TouchTestFragment.class);
    146             add("cubes test", CubesTestFragment.class);
    147             add("orientation test", OrientationTestFragment.class);
    148             add("bluetooth headset",BluetoothHeadsetFragment.class);
    149             add("bluetooth messaging test", MapMceTestFragment.class);
    150             add("car service settings", () -> {
    151                 Intent intent = new Intent(KitchenSinkActivity.this,
    152                     CarServiceSettingsActivity.class);
    153                 startActivity(intent);
    154             });
    155             add("quit", KitchenSinkActivity.this::finish);
    156         }
    157 
    158         <T extends Fragment> void add(String text, Class<T> clazz) {
    159             add(new FragmentMenuEntry(text, clazz));
    160         }
    161         void add(String text, ClickHandler onClick) {
    162             add(new OnClickMenuEntry(text, onClick));
    163         }
    164     };
    165     private Car mCarApi;
    166     private CarHvacManager mHvacManager;
    167     private CarSensorManager mCarSensorManager;
    168     private CarAppFocusManager mCarAppFocusManager;
    169 
    170     private final CarSensorManager.OnSensorChangedListener mListener = (manager, event) -> {
    171         switch (event.sensorType) {
    172             case CarSensorManager.SENSOR_TYPE_DRIVING_STATUS:
    173                 Log.d(TAG, "driving status:" + event.intValues[0]);
    174                 break;
    175         }
    176     };
    177 
    178     public CarHvacManager getHvacManager() {
    179         return mHvacManager;
    180     }
    181 
    182     @Override
    183     protected CarDrawerAdapter getRootAdapter() {
    184         return new DrawerAdapter();
    185     }
    186 
    187     @Override
    188     protected void onCreate(Bundle savedInstanceState) {
    189         super.onCreate(savedInstanceState);
    190         setMainContent(R.layout.kitchen_content);
    191         // Connection to Car Service does not work for non-automotive yet.
    192         if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
    193             mCarApi = Car.createCar(this, mCarConnectionCallback);
    194             mCarApi.connect();
    195         }
    196         Log.i(TAG, "onCreate");
    197     }
    198 
    199     @Override
    200     protected void onStart() {
    201         super.onStart();
    202         Log.i(TAG, "onStart");
    203     }
    204 
    205     @Override
    206     protected void onRestart() {
    207         super.onRestart();
    208         Log.i(TAG, "onRestart");
    209     }
    210 
    211     @Override
    212     protected void onResume() {
    213         super.onResume();
    214         Log.i(TAG, "onResume");
    215     }
    216 
    217     @Override
    218     protected void onPause() {
    219         super.onPause();
    220         Log.i(TAG, "onPause");
    221     }
    222 
    223     @Override
    224     protected void onStop() {
    225         super.onStop();
    226         Log.i(TAG, "onStop");
    227     }
    228 
    229     @Override
    230     protected void onDestroy() {
    231         super.onDestroy();
    232         if (mCarSensorManager != null) {
    233             mCarSensorManager.removeListener(mListener);
    234         }
    235         if (mCarApi != null) {
    236             mCarApi.disconnect();
    237         }
    238         Log.i(TAG, "onDestroy");
    239     }
    240 
    241     private void showFragment(Fragment fragment) {
    242         getSupportFragmentManager().beginTransaction()
    243                 .replace(R.id.kitchen_content, fragment)
    244                 .commit();
    245     }
    246 
    247     private final CarConnectionCallback mCarConnectionCallback =
    248             new CarConnectionCallback() {
    249         @Override
    250         public void onConnected(Car car) {
    251             Log.d(TAG, "Connected to Car Service");
    252             try {
    253                 mHvacManager = (CarHvacManager) mCarApi.getCarManager(android.car.Car.HVAC_SERVICE);
    254                 mCarSensorManager = (CarSensorManager) mCarApi.getCarManager(Car.SENSOR_SERVICE);
    255                 mCarSensorManager.addListener(mListener,
    256                         CarSensorManager.SENSOR_TYPE_DRIVING_STATUS,
    257                         CarSensorManager.SENSOR_RATE_NORMAL);
    258                 mCarAppFocusManager =
    259                         (CarAppFocusManager) mCarApi.getCarManager(Car.APP_FOCUS_SERVICE);
    260             } catch (CarNotConnectedException e) {
    261                 Log.e(TAG, "Car is not connected!", e);
    262             }
    263         }
    264 
    265         @Override
    266         public void onDisconnected(Car car) {
    267             Log.d(TAG, "Disconnect from Car Service");
    268         }
    269     };
    270 
    271     public Car getCar() {
    272         return mCarApi;
    273     }
    274 
    275     private final class DrawerAdapter extends CarDrawerAdapter {
    276 
    277         public DrawerAdapter() {
    278             super(KitchenSinkActivity.this, true /* showDisabledOnListOnEmpty */);
    279             setTitle(getString(R.string.app_title));
    280         }
    281 
    282         @Override
    283         protected int getActualItemCount() {
    284             return mMenuEntries.size();
    285         }
    286 
    287         @Override
    288         protected void populateViewHolder(DrawerItemViewHolder holder, int position) {
    289             holder.getTitle().setText(mMenuEntries.get(position).getText());
    290         }
    291 
    292         @Override
    293         public void onItemClick(int position) {
    294             if ((position < 0) || (position >= mMenuEntries.size())) {
    295                 Log.wtf(TAG, "Unknown menu item: " + position);
    296                 return;
    297             }
    298 
    299             mMenuEntries.get(position).onClick();
    300 
    301             closeDrawer();
    302         }
    303     }
    304 }
    305