blob: ae1d7a07b6164d7bebb5be0e051ab502d9ff397f [file] [log] [blame]
/*
* Copyright (C) 2017 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 android.car.cluster.sample;
import static android.car.cluster.sample.SampleClusterServiceImpl.LOCAL_BINDING_ACTION;
import android.car.cluster.sample.SampleClusterServiceImpl.Listener;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.util.SparseArray;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.ViewPager;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
public class MainClusterActivity extends FragmentActivity
implements Listener {
private static final String TAG = MainClusterActivity.class.getSimpleName();
private ViewPager mPager;
private SampleClusterServiceImpl mService;
private HashMap<Button, Facet<?>> mButtonToFacet = new HashMap<>();
private SparseArray<Facet<?>> mOrderToFacet = new SparseArray<>();
private InputMethodManager mInputMethodManager;
private final View.OnFocusChangeListener mFacetButtonFocusListener =
new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
mPager.setCurrentItem(mButtonToFacet.get(v).order);
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mInputMethodManager = getSystemService(InputMethodManager.class);
Intent intent = new Intent(this, SampleClusterServiceImpl.class);
intent.setAction(LOCAL_BINDING_ACTION);
bindService(intent,
new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i(TAG, "onServiceConnected, name: " + name + ", service: " + service);
mService = ((SampleClusterServiceImpl.LocalBinder) service)
.getService();
mService.registerListener(MainClusterActivity.this);
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.i(TAG, "onServiceDisconnected, name: " + name);
mService = null;
}
}, BIND_AUTO_CREATE);
registerFacets(
new Facet<>(findViewById(R.id.btn_nav), 0, NavigationFragment.class),
new Facet<>(findViewById(R.id.btn_phone), 1, PhoneFragment.class),
new Facet<>(findViewById(R.id.btn_music), 2, MusicFragment.class),
new Facet<>(findViewById(R.id.btn_car_info), 3, CarInfoFragment.class));
mPager = findViewById(R.id.pager);
mPager.setAdapter(new ClusterPageAdapter(getSupportFragmentManager()));
mOrderToFacet.get(0).button.requestFocus();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mService != null) {
mService.unregisterListener();
}
}
@Override
public void onKeyEvent(KeyEvent event) {
Log.i(TAG, "onKeyEvent, event: " + event);
// This is a hack. We use SOURCE_CLASS_POINTER here because this type of input is associated
// with the display. otherwise this event will be ignored in ViewRootImpl because injecting
// KeyEvent w/o activity being focused is useless.
event.setSource(event.getSource() | InputDevice.SOURCE_CLASS_POINTER);
mInputMethodManager.dispatchKeyEventFromInputMethod(getCurrentFocus(), event);
}
public class ClusterPageAdapter extends FragmentPagerAdapter {
public ClusterPageAdapter(FragmentManager fm) {
super(fm);
}
@Override
public int getCount() {
return mButtonToFacet.size();
}
@Override
public Fragment getItem(int position) {
return mOrderToFacet.get(position).getOrCreateFragment();
}
}
private void registerFacets(Facet<?>... facets) {
for (Facet<?> f : facets) {
registerFacet(f);
}
}
private <T> void registerFacet(Facet<T> facet) {
mOrderToFacet.append(facet.order, facet);
mButtonToFacet.put(facet.button, facet);
facet.button.setOnFocusChangeListener(mFacetButtonFocusListener);
}
private static class Facet<T> {
Button button;
Class<T> clazz;
int order;
Facet(Button button, int order, Class<T> clazz) {
this.button = button;
this.order = order;
this.clazz = clazz;
}
private Fragment mFragment;
Fragment getOrCreateFragment() {
if (mFragment == null) {
try {
mFragment = (Fragment) clazz.getConstructors()[0].newInstance();
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}
return mFragment;
}
}
SampleClusterServiceImpl getService() {
return mService;
}
}