blob: 27738bc249d20dec726df889ca303e460f0b738f [file] [log] [blame]
/*
* Copyright (C) 2018 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.google.android.car.uxr.sample;
import static android.car.drivingstate.CarDrivingStateEvent.DRIVING_STATE_IDLING;
import static android.car.drivingstate.CarDrivingStateEvent.DRIVING_STATE_MOVING;
import static android.car.drivingstate.CarDrivingStateEvent.DRIVING_STATE_PARKED;
import android.app.Activity;
import android.app.AlertDialog;
import android.car.Car;
import android.car.CarNotConnectedException;
import android.car.content.pm.CarPackageManager;
import android.car.drivingstate.CarDrivingStateEvent;
import android.car.drivingstate.CarDrivingStateManager;
import android.car.drivingstate.CarUxRestrictions;
import android.car.drivingstate.CarUxRestrictionsConfiguration;
import android.car.drivingstate.CarUxRestrictionsManager;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.JsonWriter;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.io.CharArrayWriter;
/**
* Sample app that uses components in car support library to demonstrate Car drivingstate UXR
* status.
*/
public class MainActivity extends Activity {
public static final String TAG = "drivingstate";
// Order of elements is based on number of bits shifted in value of the constants.
private static final CharSequence[] UX_RESTRICTION_NAMES = new CharSequence[]{
"BASELINE",
"NO_DIALPAD",
"NO_FILTERING",
"LIMIT_STRING_LENGTH",
"NO_KEYBOARD",
"NO_VIDEO",
"LIMIT_CONTENT",
"NO_SETUP",
"NO_TEXT_MESSAGE",
"NO_VOICE_TRANSCRIPTION",
};
private Car mCar;
private CarDrivingStateManager mCarDrivingStateManager;
private CarUxRestrictionsManager mCarUxRestrictionsManager;
private CarPackageManager mCarPackageManager;
private TextView mDrvStatus;
private TextView mDistractionOptStatus;
private TextView mUxrStatus;
private Button mToggleButton;
private Button mSampleMsgButton;
private Button mSaveUxrConfigButton;
private Button mShowStagedConfig;
private Button mShowProdConfig;
private boolean mEnableUxR;
private final ServiceConnection mCarConnectionListener =
new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder iBinder) {
Log.d(TAG, "Connected to " + name.flattenToString());
// Get Driving State & UXR manager
try {
mCarDrivingStateManager = (CarDrivingStateManager) mCar.getCarManager(
Car.CAR_DRIVING_STATE_SERVICE);
mCarUxRestrictionsManager = (CarUxRestrictionsManager) mCar.getCarManager(
Car.CAR_UX_RESTRICTION_SERVICE);
mCarPackageManager = (CarPackageManager) mCar.getCarManager(
Car.PACKAGE_SERVICE);
if (mCarDrivingStateManager != null) {
mCarDrivingStateManager.registerListener(mDrvStateChangeListener);
updateDrivingStateText(
mCarDrivingStateManager.getCurrentCarDrivingState());
}
if (mCarUxRestrictionsManager != null) {
mCarUxRestrictionsManager.registerListener(mUxRChangeListener);
updateUxRText(mCarUxRestrictionsManager.getCurrentCarUxRestrictions());
}
} catch (CarNotConnectedException e) {
Log.e(TAG, "Failed to get a connection", e);
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d(TAG, "Disconnected from " + name.flattenToString());
mCarDrivingStateManager = null;
mCarUxRestrictionsManager = null;
mCarPackageManager = null;
}
};
private void updateUxRText(CarUxRestrictions restrictions) {
mDistractionOptStatus.setText(
restrictions.isRequiresDistractionOptimization()
? "Requires Distraction Optimization"
: "No Distraction Optimization required");
mUxrStatus.setText("Active Restrictions : 0x"
+ Integer.toHexString(restrictions.getActiveRestrictions())
+ " - "
+ Integer.toBinaryString(restrictions.getActiveRestrictions()));
mDistractionOptStatus.requestLayout();
mUxrStatus.requestLayout();
}
private void updateToggleUxREnable() {
if (mCarPackageManager == null) {
return;
}
mCarPackageManager.setEnableActivityBlocking(mEnableUxR);
if (mEnableUxR) {
mToggleButton.setText("Disable UX Restrictions");
} else {
mToggleButton.setText("Enable UX Restrictions");
}
mEnableUxR = !mEnableUxR;
mToggleButton.requestLayout();
}
private void updateDrivingStateText(CarDrivingStateEvent state) {
if (state == null) {
return;
}
String displayText;
switch (state.eventValue) {
case DRIVING_STATE_PARKED:
displayText = "Parked";
break;
case DRIVING_STATE_IDLING:
displayText = "Idling";
break;
case DRIVING_STATE_MOVING:
displayText = "Moving";
break;
default:
displayText = "Unknown";
}
mDrvStatus.setText("Driving State: " + displayText);
mDrvStatus.requestLayout();
}
private CarUxRestrictionsManager.OnUxRestrictionsChangedListener mUxRChangeListener =
this::updateUxRText;
private CarDrivingStateManager.CarDrivingStateEventListener mDrvStateChangeListener =
this::updateDrivingStateText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
mDrvStatus = findViewById(R.id.driving_state);
mDistractionOptStatus = findViewById(R.id.do_status);
mUxrStatus = findViewById(R.id.uxr_status);
mToggleButton = findViewById(R.id.toggle_status);
mSaveUxrConfigButton = findViewById(R.id.save_uxr_config);
mSaveUxrConfigButton.setOnClickListener(v -> saveUxrConfig());
mShowStagedConfig = findViewById(R.id.show_staged_config);
mShowStagedConfig.setOnClickListener(v -> showStagedUxRestrictionsConfig());
mShowProdConfig = findViewById(R.id.show_prod_config);
mShowProdConfig.setOnClickListener(v -> showProdUxRestrictionsConfig());
mToggleButton.setOnClickListener(v -> updateToggleUxREnable());
mSampleMsgButton = findViewById(R.id.launch_message);
mSampleMsgButton.setOnClickListener(this::launchSampleMsgActivity);
// Connect to car service
mCar = Car.createCar(this, mCarConnectionListener);
mCar.connect();
}
private void saveUxrConfig() {
// Pop up a dialog to build the IDLING restrictions.
boolean[] selected = new boolean[UX_RESTRICTION_NAMES.length];
new AlertDialog.Builder(this)
.setTitle(R.string.set_uxr_config_dialog_title)
.setMultiChoiceItems(UX_RESTRICTION_NAMES, null,
(dialog, which, isChecked) -> selected[which] = isChecked)
.setPositiveButton(R.string.set_uxr_config_dialog_positive_button,
(dialog, id) -> setUxRestrictionsConfig(selected))
.setNegativeButton(R.string.set_uxr_config_dialog_negative_button, null)
.show();
}
private void setUxRestrictionsConfig(boolean[] selected) {
int selectedRestrictions = 0;
// Iteration starts at 1 because 0 is BASELINE (no restrictions).
for (int i = 1; i < selected.length; i++) {
if (selected[i]) {
selectedRestrictions += 1 << (i - 1);
}
}
boolean reqOpt = selectedRestrictions != 0;
CarUxRestrictionsConfiguration config = new CarUxRestrictionsConfiguration.Builder()
.setUxRestrictions(DRIVING_STATE_PARKED, false, 0)
.setUxRestrictions(DRIVING_STATE_IDLING, reqOpt, selectedRestrictions)
.setUxRestrictions(DRIVING_STATE_MOVING, reqOpt, selectedRestrictions)
.build();
try {
mCarUxRestrictionsManager.saveUxRestrictionsConfigurationForNextBoot(config);
} catch (CarNotConnectedException e) {
Log.e(TAG, "Car not connected", e);
}
}
private void showStagedUxRestrictionsConfig() {
try {
CarUxRestrictionsConfiguration stagedConfig =
mCarUxRestrictionsManager.getStagedConfig();
if (stagedConfig == null) {
new AlertDialog.Builder(this)
.setMessage(R.string.no_staged_config)
.show();
return;
}
CharArrayWriter charWriter = new CharArrayWriter();
JsonWriter writer = new JsonWriter(charWriter);
writer.setIndent("\t");
stagedConfig.writeJson(writer);
new AlertDialog.Builder(this)
.setTitle(R.string.staged_config_title)
.setMessage(charWriter.toString())
.show();
} catch (CarNotConnectedException e) {
Log.e(TAG, "Car not connected", e);
} catch (Exception e) {
e.printStackTrace();
}
}
private void showProdUxRestrictionsConfig() {
try {
CarUxRestrictionsConfiguration prodConfig =
mCarUxRestrictionsManager.getConfig();
if (prodConfig == null) {
new AlertDialog.Builder(this)
.setMessage(R.string.no_prod_config)
.show();
return;
}
CharArrayWriter charWriter = new CharArrayWriter();
JsonWriter writer = new JsonWriter(charWriter);
writer.setIndent("\t");
prodConfig.writeJson(writer);
new AlertDialog.Builder(this)
.setTitle(R.string.prod_config_title)
.setMessage(charWriter.toString())
.show();
} catch (CarNotConnectedException e) {
Log.e(TAG, "Car not connected", e);
} catch (Exception e) {
e.printStackTrace();
}
}
private void launchSampleMsgActivity(View view) {
Intent msgIntent = new Intent(this, SampleMessageActivity.class);
startActivity(msgIntent);
}
@Override
protected void onDestroy() {
super.onDestroy();
try {
if (mCarUxRestrictionsManager != null) {
mCarUxRestrictionsManager.unregisterListener();
}
if (mCarDrivingStateManager != null) {
mCarDrivingStateManager.unregisterListener();
}
} catch (CarNotConnectedException e) {
Log.e(TAG, "Error unregistering listeners", e);
}
if (mCar != null) {
mCar.disconnect();
}
}
}