1 /* 2 * Copyright (C) 2021 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.android.car.settings.qc; 18 19 import android.app.PendingIntent; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.net.Uri; 23 import android.os.Bundle; 24 25 import com.android.car.qc.QCItem; 26 27 import java.lang.reflect.Constructor; 28 import java.lang.reflect.InvocationTargetException; 29 30 /** 31 * Base class for QCItems provided by CarSettings. 32 */ 33 public abstract class SettingsQCItem { 34 35 private final Context mContext; 36 SettingsQCItem(Context context)37 public SettingsQCItem(Context context) { 38 mContext = context; 39 } 40 41 /** 42 * @return an complete instance of the {@link QCItem}. 43 */ getQCItem()44 abstract QCItem getQCItem(); 45 46 /** 47 * @return a {@link android.content.ContentResolver#SCHEME_CONTENT content} {@link Uri} which 48 * backs the {@link QCItem} returned by {@link #getQCItem()}. 49 */ getUri()50 abstract Uri getUri(); 51 52 /** 53 * @return the context for the {@link SettingsQCItem}. 54 */ getContext()55 protected Context getContext() { 56 return mContext; 57 } 58 59 /** 60 * Handles the actions sent by the {@link Intent intents} bound to the {@link QCItem} returned 61 * by {@link #getQCItem()}. 62 * 63 * @param intent which has the action taken on a {@link QCItem}. 64 */ onNotifyChange(Intent intent)65 void onNotifyChange(Intent intent) {} 66 67 /** 68 * Standardize the primary intent for the QCItem. 69 */ getActivityIntent(Intent intent)70 PendingIntent getActivityIntent(Intent intent) { 71 return PendingIntent.getActivity(getContext(), 72 0 /* requestCode */, intent, 73 PendingIntent.FLAG_IMMUTABLE); 74 } 75 76 /** 77 * See {@link #getBroadcastIntent(Bundle, int)} 78 */ getBroadcastIntent()79 PendingIntent getBroadcastIntent() { 80 return getBroadcastIntent(/* extras= */ null); 81 } 82 83 /** 84 * See {@link #getBroadcastIntent(Bundle, int)} 85 */ getBroadcastIntent(Bundle extras)86 PendingIntent getBroadcastIntent(Bundle extras) { 87 return getBroadcastIntent(extras, /* requestCode= */ 0); 88 } 89 90 /** 91 * Standardize the intents returned to indicate actions by the QCItem. 92 * <p> 93 * The {@link PendingIntent} is linked to {@link SettingsQCBroadcastReceiver} where the 94 * Intent Action is found by {@code getUri().toString()}. 95 * 96 * @return a {@link PendingIntent} linked to {@link SettingsQCBroadcastReceiver}. 97 */ getBroadcastIntent(Bundle extras, int requestCode)98 PendingIntent getBroadcastIntent(Bundle extras, int requestCode) { 99 Intent intent = new Intent(getUri().toString()) 100 .setData(getUri()) 101 .setClass(getContext(), SettingsQCBroadcastReceiver.class) 102 .addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 103 if (extras != null) { 104 intent.putExtras(extras); 105 } 106 return PendingIntent.getBroadcast(getContext(), requestCode, intent, 107 PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE); 108 } 109 110 /** 111 * Build an instance of a {@link SettingsQCItem} which has a {@link Context}-only constructor. 112 */ createInstance(Context context, Class<? extends SettingsQCItem> qcItem)113 static SettingsQCItem createInstance(Context context, 114 Class<? extends SettingsQCItem> qcItem) { 115 try { 116 Constructor<? extends SettingsQCItem> constructor = 117 qcItem.getConstructor(Context.class); 118 Object[] params = new Object[]{context.getApplicationContext()}; 119 return constructor.newInstance(params); 120 } catch (NoSuchMethodException | InstantiationException | IllegalArgumentException 121 | InvocationTargetException | IllegalAccessException e) { 122 throw new IllegalStateException( 123 "Invalid SettingsQCItem class: " + qcItem, e); 124 } 125 } 126 127 /** 128 * Settings QCItems which require background work, such as updating lists should implement a 129 * {@link SettingsQCBackgroundWorker} and return it here. An example of background work is 130 * updating a list of Wifi networks available in the area. 131 * 132 * @return a {@link Class<? extends SettingsQCBackgroundWorker>} to perform background work for 133 * the QCItem. 134 */ getBackgroundWorkerClass()135 Class<? extends SettingsQCBackgroundWorker> getBackgroundWorkerClass() { 136 return null; 137 } 138 } 139