[DO NOT MERGE] Fast Pair Half Sheet UI implementation
Refactor doc: go/fp-halfsheet-aosp
Test: Built band verified flow manually
Change-Id: I2496d111410e9bc715547b8fdbe708730304df8c
diff --git a/nearby/halfsheet/res/drawable/fast_pair_ic_info.xml b/nearby/halfsheet/res/drawable/fast_pair_ic_info.xml
index cc514e5..7d61d1c 100644
--- a/nearby/halfsheet/res/drawable/fast_pair_ic_info.xml
+++ b/nearby/halfsheet/res/drawable/fast_pair_ic_info.xml
@@ -17,7 +17,8 @@
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
- android:viewportHeight="24.0">
+ android:viewportHeight="24.0"
+ android:tint="@color/fast_pair_half_sheet_subtitle_color">
<path
android:fillColor="@color/fast_pair_half_sheet_subtitle_color"
android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2L13,7h-2v2z"/>
diff --git a/nearby/halfsheet/res/layout/fast_pair_device_pairing_fragment.xml b/nearby/halfsheet/res/layout/fast_pair_device_pairing_fragment.xml
index 24fcd83..7fbe229 100644
--- a/nearby/halfsheet/res/layout/fast_pair_device_pairing_fragment.xml
+++ b/nearby/halfsheet/res/layout/fast_pair_device_pairing_fragment.xml
@@ -73,50 +73,67 @@
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="horizontal"
app:layout_constraintTop_toBottomOf="@+id/connect_progressbar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
+
<ImageView
android:id="@+id/info_icon"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ app:srcCompat="@drawable/fast_pair_ic_info"
android:layout_centerInParent="true"
android:contentDescription="@null"
android:layout_marginEnd="10dp"
android:layout_toStartOf="@id/connect_btn"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
- <Button
+ android:visibility="invisible" />
+
+ <com.google.android.material.button.MaterialButton
android:id="@+id/connect_btn"
- android:text="@string/common_connect"
- android:layout_height="wrap_content"
android:layout_width="@dimen/fast_pair_half_sheet_image_size"
+ android:layout_height="wrap_content"
+ android:text="@string/paring_action_connect"
android:layout_centerInParent="true"
- android:background="@color/fast_pair_half_sheet_button_color"
style="@style/HalfSheetButton" />
+
</RelativeLayout>
- <Button
+ <com.google.android.material.button.MaterialButton
+ android:id="@+id/settings_btn"
+ android:text="@string/paring_action_settings"
+ android:layout_height="wrap_content"
+ android:layout_width="@dimen/fast_pair_half_sheet_image_size"
+ app:layout_constraintTop_toBottomOf="@+id/connect_progressbar"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ android:visibility="invisible"
+ style="@style/HalfSheetButton" />
+
+ <com.google.android.material.button.MaterialButton
android:id="@+id/cancel_btn"
- android:text="@string/common_done"
- android:visibility="gone"
+ android:text="@string/paring_action_done"
+ android:visibility="invisible"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:gravity="start|center_vertical"
android:layout_marginTop="6dp"
- android:layout_marginBottom="16dp"
style="@style/HalfSheetButtonBorderless"/>
- <Button
+ <com.google.android.material.button.MaterialButton
android:id="@+id/setup_btn"
+ android:text="@string/paring_action_launch"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginTop="6dp"
android:layout_marginBottom="16dp"
android:background="@color/fast_pair_half_sheet_button_color"
- android:visibility="gone"
+ android:visibility="invisible"
android:layout_height="@dimen/fast_pair_half_sheet_bottom_button_height"
android:layout_width="wrap_content"
style="@style/HalfSheetButton" />
+
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
diff --git a/nearby/halfsheet/res/values/strings.xml b/nearby/halfsheet/res/values/strings.xml
index 12e3c23..01a82e4 100644
--- a/nearby/halfsheet/res/values/strings.xml
+++ b/nearby/halfsheet/res/values/strings.xml
@@ -16,9 +16,57 @@
<resources>
- <string name="common_done" description="After pairing process finish button text to dismiss halfsheet">Done</string>
- <string name="common_save">Save</string>
- <string name="common_connect" description="Button text to start connecting process">Connect</string>
- <string name="fast_pair_app_launch_button" description="String on app launch half sheet button.">Set up</string>
+ <!--
+ ============================================================
+ PAIRING FRAGMENT
+ ============================================================
+ -->
+ <!--
+ A button shown to remind user setup is in progress. [CHAR LIMIT=30]
+ -->
+ <string name="fast_pair_setup_in_progress">Starting Setup…</string>
+ <!--
+ Title text shown to remind user to setup a device through companion app. [CHAR LIMIT=40]
+ -->
+ <string name="fast_pair_title_setup">Set up device</string>
+ <!--
+ Title after we successfully pair with the audio device
+ [CHAR LIMIT=30]
+ -->
+ <string name="fast_pair_device_ready">Device connected</string>
+ <!-- Title text shown when peripheral device fail to connect to phone. [CHAR_LIMIT=30] -->
+ <string name="fast_pair_title_fail">Couldn\'t connect</string>
+
+ <!--
+ ============================================================
+ MISCELLANEOUS
+ ============================================================
+ -->
+
+ <!--
+ A button shown after paring process to dismiss the current activity.
+ [CHAR LIMIT=30]
+ -->
+ <string name="paring_action_done">Done</string>
+ <!--
+ A button shown for retroactive paring.
+ [CHAR LIMIT=30]
+ -->
+ <string name="paring_action_save">Save</string>
+ <!--
+ A button to start connecting process.
+ [CHAR LIMIT=30]
+ -->
+ <string name="paring_action_connect">Connect</string>
+ <!--
+ A button to launch a companion app.
+ [CHAR LIMIT=30]
+ -->
+ <string name="paring_action_launch">Set up</string>
+ <!--
+ A button to launch a bluetooth Settings page.
+ [CHAR LIMIT=20]
+ -->
+ <string name="paring_action_settings">Settings</string>
</resources>
\ No newline at end of file
diff --git a/nearby/halfsheet/res/values/styles.xml b/nearby/halfsheet/res/values/styles.xml
index b48da70..917bb63 100644
--- a/nearby/halfsheet/res/values/styles.xml
+++ b/nearby/halfsheet/res/values/styles.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
- <style name="HalfSheetStyle" parent="Theme.MaterialComponents.DayNight.NoActionBar">
+ <style name="HalfSheetStyle" parent="Theme.Material3.DayNight.NoActionBar">
<item name="android:windowFrame">@null</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowEnterAnimation">@anim/fast_pair_half_sheet_slide_in</item>
@@ -14,7 +14,7 @@
<item name="android:windowTranslucentNavigation">true</item>
</style>
- <style name="HalfSheetButton" parent="@style/Widget.MaterialComponents.Button.TextButton">
+ <style name="HalfSheetButton" parent="@style/Widget.Material3.Button.TonalButton">
<item name="android:textColor">@color/fast_pair_half_sheet_button_accent_text</item>
<item name="android:backgroundTint">@color/fast_pair_half_sheet_button_color</item>
<item name="android:textSize">@dimen/fast_pair_notification_text_size</item>
@@ -23,8 +23,7 @@
<item name="android:textAllCaps">false</item>
</style>
- <style name="HalfSheetButtonBorderless"
- parent="@style/Widget.MaterialComponents.Button.OutlinedButton">
+ <style name="HalfSheetButtonBorderless" parent="@style/Widget.Material3.Button.OutlinedButton">
<item name="android:textColor">@color/fast_pair_half_sheet_button_text</item>
<item name="android:strokeColor">@color/fast_pair_half_sheet_button_color</item>
<item name="android:textAllCaps">false</item>
diff --git a/nearby/halfsheet/src/com/android/nearby/halfsheet/HalfSheetActivity.java b/nearby/halfsheet/src/com/android/nearby/halfsheet/HalfSheetActivity.java
index c495c35..9507b9b 100644
--- a/nearby/halfsheet/src/com/android/nearby/halfsheet/HalfSheetActivity.java
+++ b/nearby/halfsheet/src/com/android/nearby/halfsheet/HalfSheetActivity.java
@@ -19,22 +19,18 @@
import static com.android.nearby.halfsheet.fragment.DevicePairingFragment.APP_LAUNCH_FRAGMENT_TYPE;
import static com.android.server.nearby.common.bluetooth.fastpair.FastPairConstants.EXTRA_MODEL_ID;
import static com.android.server.nearby.common.fastpair.service.UserActionHandlerBase.EXTRA_MAC_ADDRESS;
-import static com.android.server.nearby.fastpair.Constant.ACTION_FAST_PAIR_HALF_SHEET_BAN_STATE_RESET;
import static com.android.server.nearby.fastpair.Constant.ACTION_FAST_PAIR_HALF_SHEET_CANCEL;
import static com.android.server.nearby.fastpair.Constant.DEVICE_PAIRING_FRAGMENT_TYPE;
import static com.android.server.nearby.fastpair.Constant.EXTRA_HALF_SHEET_INFO;
import static com.android.server.nearby.fastpair.Constant.EXTRA_HALF_SHEET_TYPE;
-import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
-import android.util.DisplayMetrics;
import android.util.Log;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.FragmentActivity;
import com.android.nearby.halfsheet.fragment.DevicePairingFragment;
@@ -48,14 +44,12 @@
import service.proto.Cache;
/**
- * Half sheet activity to show pairing ux.
+ * A class show Fast Pair related information in Half sheet format.
*/
public class HalfSheetActivity extends FragmentActivity {
- public static final String EXTRA_HALF_SHEET_PENDING_INTENT_CALL_BACK =
- "com.android.nearby.halfsheet.EXTRA_HALF_SHEET_PENDING_INTENT_CALL_BACK";
- public static final String EXTRA_HALF_SHEET_PACKAGE_NAME =
- "com.android.nearby.halfsheet.EXTRA_HALF_SHEET_PACKAGE_NAME";
+ public static final String TAG = "HalfSheetActivity";
+
public static final String EXTRA_HALF_SHEET_CONTENT =
"com.android.nearby.halfsheet.HALF_SHEET_CONTENT";
public static final String EXTRA_TITLE =
@@ -72,38 +66,11 @@
"com.android.nearby.halfsheet.EXTRA_HALF_SHEET_PAIRING_RESURFACE";
public static final String ACTION_HALF_SHEET_FOREGROUND_STATE =
"com.android.nearby.halfsheet.ACTION_HALF_SHEET_FOREGROUND_STATE";
- public static final String ACTION_HALF_SHEET_BAN_ALL_ITEM =
- "com.android.nearby.halfsheet.ACTION_HALF_SHEET_BAN_ALL_ITEM";
- public static final String ACTION_HALF_SHEET_APP_LAUNCH_CLICKED =
- "com.android.nearby.halfsheet.ACTION_HALF_SHEET_APP_LAUNCH_CLICKED";
- public static final String ACTION_HALF_SHEET_WEAR_OS_CLICKED =
- "com.android.nearby.halfsheet.ACTION_HALF_SHEET_WEAR_OS_CLICKED";
- public static final String ACTION_HALF_SHEET_USER_COMPLETE_CONFIRMATION =
- "com.android.nearby.halfsheet.ACTION_HALF_SHEET_USER_COMPLETE_CONFIRMATION";
- public static final String ACTION_FAST_PAIR_HANDLE_CHIP_DEVICE =
- "com.android.nearby.halfsheet.ACTION_FAST_PAIR_HANDLE_CHIP_DEVICE";
- // Intent extra contains another intent that will trigger DiscoveryChimeraService to upload
- // device
- // information to the cloud.
- public static final String EXTRA_HALF_SHEET_CLOUD_SYNC_INTENT =
- "com.android.nearby.halfsheet.HALF_SHEET_CLOUD_SYNC_INTENT";
// Intent extra contains the user gmail name eg. testaccount@gmail.com.
public static final String EXTRA_HALF_SHEET_ACCOUNT_NAME =
"com.android.nearby.halfsheet.HALF_SHEET_ACCOUNT_NAME";
public static final String EXTRA_HALF_SHEET_FOREGROUND =
"com.android.nearby.halfsheet.EXTRA_HALF_SHEET_FOREGROUND";
- public static final String EXTRA_USER_CONSENT_SYNC_CONTACTS =
- "com.android.nearby.halfsheet.EXTRA_USER_CONSENT_SYNC_CONTACTS";
- public static final String EXTRA_USER_CONSENT_SYNC_SMS =
- "com.android.nearby.halfsheet.EXTRA_USER_CONSENT_SYNC_SMS";
- public static final String EXTRA_USER_CONFIRM_PASSKEY =
- "com.android.nearby.halfsheet.EXTRA_USER_CONFIRM_PASSKEY";
- public static final String CLASS_NAME =
- "com.android.nearby.halfsheet.HalfSheetActivity";
- public static final String ACTION_HALF_SHEET_STATUS_CHANGE =
- "com.android.nearby.halfsheet.ACTION_HALF_SHEET_STATUS_CHANGE";
- public static final String FINISHED_STATE = "FINISHED_STATE";
- public static final String EXTRA_CLASSIC_MAC_ADDRESS = "EXTRA_CLASSIC_MAC_ADDRESS";
public static final String ARG_FRAGMENT_STATE = "ARG_FRAGMENT_STATE";
@Nullable
private HalfSheetModuleFragment mHalfSheetModuleFragment;
@@ -128,7 +95,7 @@
mHalfSheetModuleFragment = DevicePairingFragment.newInstance(getIntent(),
savedInstanceState);
if (mHalfSheetModuleFragment == null) {
- Log.d("HalfSheetActivity", "device pairing fragment has error.");
+ Log.d(TAG, "device pairing fragment has error.");
finish();
return;
}
@@ -136,13 +103,13 @@
case APP_LAUNCH_FRAGMENT_TYPE:
// currentFragment = AppLaunchFragment.newInstance(getIntent());
if (mHalfSheetModuleFragment == null) {
- Log.v("HalfSheetActivity", "app launch fragment has error.");
+ Log.v(TAG, "app launch fragment has error.");
finish();
return;
}
break;
default:
- Log.w("HalfSheetActivity", "there is no valid type for half sheet");
+ Log.w(TAG, "there is no valid type for half sheet");
finish();
return;
}
@@ -159,23 +126,19 @@
findViewById(R.id.background).setOnClickListener(v -> onCancelClicked());
findViewById(R.id.card)
.setOnClickListener(
- v -> Log.v("HalfSheetActivity", "card view is clicked noop"));
+ v -> Log.v(TAG, "card view is clicked noop"));
try {
mScanFastPairStoreItem =
Cache.ScanFastPairStoreItem.parseFrom(infoArray);
} catch (InvalidProtocolBufferException e) {
Log.w(
- "HalfSheetActivity", "error happens when pass info to half sheet");
+ TAG, "error happens when pass info to half sheet");
}
}
@Override
protected void onStart() {
super.onStart();
- BroadcastUtils.sendBroadcast(
- this,
- new Intent(ACTION_HALF_SHEET_FOREGROUND_STATE)
- .putExtra(EXTRA_HALF_SHEET_FOREGROUND, true));
}
@Override
@@ -217,17 +180,18 @@
mScanFastPairStoreItem.getAddress())
&& testScanFastPairStoreItem.getModelId().equals(
mScanFastPairStoreItem.getModelId())) {
- Log.d("HalfSheetActivity", "possible factory reset happens");
+ Log.d(TAG, "possible factory reset happens");
halfSheetStateChange();
}
} catch (InvalidProtocolBufferException | NullPointerException e) {
- Log.w("HalfSheetActivity", "error happens when pass info to half sheet");
+ Log.w(TAG, "error happens when pass info to half sheet");
}
}
}
/** This function should be called when user click empty area and cancel button. */
public void onCancelClicked() {
+ Log.d(TAG, "Cancels the half sheet and paring.");
sendHalfSheetCancelBroadcast();
finish();
}
@@ -241,20 +205,6 @@
finish();
}
- /**
- * Change the half sheet ban state to active sometimes users leave half sheet to go to fast pair
- * info page we do not want the behavior to be counted as dismiss.
- */
- public void sendBanStateResetBroadcast() {
- if (mScanFastPairStoreItem != null) {
- BroadcastUtils.sendBroadcast(
- this,
- new Intent(ACTION_FAST_PAIR_HALF_SHEET_BAN_STATE_RESET)
- .putExtra(EXTRA_MODEL_ID,
- mScanFastPairStoreItem.getModelId().toLowerCase(Locale.ROOT)));
- }
- }
-
private void sendHalfSheetCancelBroadcast() {
BroadcastUtils.sendBroadcast(
this,
@@ -280,31 +230,10 @@
}
}
- @Nullable
- @VisibleForTesting
- public HalfSheetModuleFragment getFragmentModel() {
- return mHalfSheetModuleFragment;
- }
-
@Override
public void setTitle(CharSequence title) {
super.setTitle(title);
TextView toolbarTitle = findViewById(R.id.toolbar_title);
toolbarTitle.setText(title);
}
-
-
- /**
- * This method converts dp unit to equivalent pixels, depending on device density.
- *
- * @param dp A value in dp (density independent pixels) unit, which we need to convert into
- * pixels
- * @param context Context to get resources and device specific display metrics
- * @return A float value to represent px equivalent to dp depending on device density
- */
- private float convertDpToPixel(float dp, Context context) {
- return dp
- * ((float) context.getResources().getDisplayMetrics().densityDpi
- / DisplayMetrics.DENSITY_DEFAULT);
- }
}
diff --git a/nearby/halfsheet/src/com/android/nearby/halfsheet/fragment/DevicePairingFragment.java b/nearby/halfsheet/src/com/android/nearby/halfsheet/fragment/DevicePairingFragment.java
index 74530de..a62c8cc 100644
--- a/nearby/halfsheet/src/com/android/nearby/halfsheet/fragment/DevicePairingFragment.java
+++ b/nearby/halfsheet/src/com/android/nearby/halfsheet/fragment/DevicePairingFragment.java
@@ -17,44 +17,35 @@
import static android.text.TextUtils.isEmpty;
-import static com.android.nearby.halfsheet.HalfSheetActivity.ACTION_HALF_SHEET_STATUS_CHANGE;
import static com.android.nearby.halfsheet.HalfSheetActivity.ARG_FRAGMENT_STATE;
-import static com.android.nearby.halfsheet.HalfSheetActivity.EXTRA_CLASSIC_MAC_ADDRESS;
import static com.android.nearby.halfsheet.HalfSheetActivity.EXTRA_DESCRIPTION;
import static com.android.nearby.halfsheet.HalfSheetActivity.EXTRA_HALF_SHEET_ACCOUNT_NAME;
import static com.android.nearby.halfsheet.HalfSheetActivity.EXTRA_HALF_SHEET_CONTENT;
import static com.android.nearby.halfsheet.HalfSheetActivity.EXTRA_HALF_SHEET_ID;
-import static com.android.nearby.halfsheet.HalfSheetActivity.EXTRA_HALF_SHEET_IS_RETROACTIVE;
-import static com.android.nearby.halfsheet.HalfSheetActivity.EXTRA_HALF_SHEET_IS_SUBSEQUENT_PAIR;
-import static com.android.nearby.halfsheet.HalfSheetActivity.EXTRA_HALF_SHEET_PAIRING_RESURFACE;
import static com.android.nearby.halfsheet.HalfSheetActivity.EXTRA_TITLE;
-import static com.android.nearby.halfsheet.HalfSheetActivity.FINISHED_STATE;
+import static com.android.nearby.halfsheet.HalfSheetActivity.TAG;
+import static com.android.nearby.halfsheet.fragment.HalfSheetModuleFragment.HalfSheetFragmentState.FAILED;
+import static com.android.nearby.halfsheet.fragment.HalfSheetModuleFragment.HalfSheetFragmentState.FOUND_DEVICE;
import static com.android.nearby.halfsheet.fragment.HalfSheetModuleFragment.HalfSheetFragmentState.NOT_STARTED;
-import static com.android.nearby.halfsheet.fragment.HalfSheetModuleFragment.HalfSheetFragmentState.RESULT_FAILURE;
-import static com.android.server.nearby.common.bluetooth.fastpair.FastPairConstants.EXTRA_MODEL_ID;
-import static com.android.server.nearby.fastpair.Constant.DISMISS;
+import static com.android.nearby.halfsheet.fragment.HalfSheetModuleFragment.HalfSheetFragmentState.PAIRED_LAUNCHABLE;
+import static com.android.nearby.halfsheet.fragment.HalfSheetModuleFragment.HalfSheetFragmentState.PAIRED_UNLAUNCHABLE;
+import static com.android.nearby.halfsheet.fragment.HalfSheetModuleFragment.HalfSheetFragmentState.PAIRING;
import static com.android.server.nearby.fastpair.Constant.EXTRA_BINDER;
import static com.android.server.nearby.fastpair.Constant.EXTRA_BUNDLE;
import static com.android.server.nearby.fastpair.Constant.EXTRA_HALF_SHEET_INFO;
-import static com.android.server.nearby.fastpair.Constant.FAIL_STATE;
-import static com.android.server.nearby.fastpair.Constant.SUCCESS_STATE;
-import static com.android.server.nearby.fastpair.UserActionHandler.ACTION_FAST_PAIR;
-import static com.android.server.nearby.fastpair.UserActionHandler.EXTRA_PRIVATE_BLE_ADDRESS;
-import android.animation.AnimatorSet;
-import android.app.Activity;
-import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothManager;
-import android.content.BroadcastReceiver;
-import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
import android.content.res.Configuration;
-import android.nearby.IFastPairHalfSheetCallback;
+import android.graphics.Bitmap;
+import android.nearby.FastPairClient;
+import android.nearby.FastPairDevice;
+import android.nearby.FastPairStatusCallback;
+import android.nearby.NearbyDevice;
+import android.nearby.PairStatusMetadata;
import android.os.Bundle;
-import android.os.RemoteException;
import android.provider.Settings;
+import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
@@ -69,12 +60,13 @@
import com.android.nearby.halfsheet.HalfSheetActivity;
import com.android.nearby.halfsheet.R;
-import com.android.nearby.halfsheet.utils.BroadcastUtils;
import com.android.nearby.halfsheet.utils.FastPairUtils;
-import com.android.server.nearby.fastpair.UserActionHandler;
+import com.android.nearby.halfsheet.utils.IconUtils;
import com.google.protobuf.InvalidProtocolBufferException;
+import java.util.Objects;
+
import service.proto.Cache.ScanFastPairStoreItem;
/**
@@ -83,36 +75,38 @@
* <p>This fragment will handle initial pairing subsequent pairing and retroactive pairing.
*/
@SuppressWarnings("nullness")
-public class DevicePairingFragment extends HalfSheetModuleFragment {
+public class DevicePairingFragment extends HalfSheetModuleFragment implements
+ FastPairStatusCallback {
+ private TextView mTitleView;
+ private TextView mSubTitleView;
+ private ImageView mImage;
+
private Button mConnectButton;
private Button mSetupButton;
private Button mCancelButton;
+ // Opens Bluetooth Settings.
+ private Button mSettingsButton;
private ImageView mInfoIconButton;
private ProgressBar mConnectProgressBar;
- private View mRootView;
- private TextView mSubTitle;
- private TextView mTitle;
- private ImageView mImage;
- private ScanFastPairStoreItem mScanFastPairStoreItem;
- // This open companion app intent will be triggered after user finish Fast Pair.
- private Intent mOpenCompanionAppIntent;
- // Indicates that the setup button is clicked before.
- private boolean mSetupButtonClicked = false;
- private boolean mIsSubsequentPair = false;
- private boolean mIsPairingResurface = false;
- private String mBluetoothMacAddress = "";
- private HalfSheetFragmentState mFragmentState = NOT_STARTED;
- private AnimatorSet mAnimatorSet = new AnimatorSet();
- // True means pairing was successful and false means failed.
- private Boolean mPairingResult = false;
+
private Bundle mBundle;
- public static final String APP_LAUNCH_FRAGMENT_TYPE = "APP_LAUNCH";
- public static final String FAST_PAIR_CONSENT_FRAGMENT_TYPE = "FAST_PAIR_CONSENT";
- private static final String ARG_SETUP_BUTTON_CLICKED = "SETUP_BUTTON_CLICKED";
- public static final String RESULT_FAIL = "RESULT_FAIL";
- private static final String ARG_PAIRING_RESULT = "PAIRING_RESULT";
+ private ScanFastPairStoreItem mScanFastPairStoreItem;
+ private FastPairClient mFastPairClient;
+ private @PairStatusMetadata.Status int mPairStatus = PairStatusMetadata.Status.UNKNOWN;
+ // True when there is a companion app to open.
+ private boolean mIsLaunchable;
+ private boolean mIsConnecting;
+ // Indicates that the setup button is clicked before.
+ private boolean mSetupButtonClicked = false;
+
+ // Holds the new text while we transition between the two.
+ private static final int TAG_PENDING_TEXT = R.id.toolbar_title;
+ public static final String APP_LAUNCH_FRAGMENT_TYPE = "APP_LAUNCH";
+
+ private static final String ARG_SETUP_BUTTON_CLICKED = "SETUP_BUTTON_CLICKED";
+ private static final String ARG_PAIRING_RESULT = "PAIRING_RESULT";
/**
* Create certain fragment according to the intent.
@@ -122,23 +116,15 @@
Intent intent, @Nullable Bundle saveInstanceStates) {
Bundle args = new Bundle();
byte[] infoArray = intent.getByteArrayExtra(EXTRA_HALF_SHEET_INFO);
- boolean isRetroactive = intent.getBooleanExtra(EXTRA_HALF_SHEET_IS_RETROACTIVE, false);
- boolean isSubsequentPair = intent.getBooleanExtra(EXTRA_HALF_SHEET_IS_SUBSEQUENT_PAIR,
- false);
- boolean isPairingResurface = intent.getBooleanExtra(EXTRA_HALF_SHEET_PAIRING_RESURFACE,
- false);
+
Bundle bundle = intent.getBundleExtra(EXTRA_BUNDLE);
String title = intent.getStringExtra(EXTRA_TITLE);
String description = intent.getStringExtra(EXTRA_DESCRIPTION);
String accountName = intent.getStringExtra(EXTRA_HALF_SHEET_ACCOUNT_NAME);
String result = intent.getStringExtra(EXTRA_HALF_SHEET_CONTENT);
- String publicAddress = intent.getStringExtra(EXTRA_CLASSIC_MAC_ADDRESS);
int halfSheetId = intent.getIntExtra(EXTRA_HALF_SHEET_ID, 0);
args.putByteArray(EXTRA_HALF_SHEET_INFO, infoArray);
- args.putBoolean(EXTRA_HALF_SHEET_IS_RETROACTIVE, isRetroactive);
- args.putBoolean(EXTRA_HALF_SHEET_IS_SUBSEQUENT_PAIR, isSubsequentPair);
- args.putBoolean(EXTRA_HALF_SHEET_PAIRING_RESURFACE, isPairingResurface);
args.putString(EXTRA_HALF_SHEET_ACCOUNT_NAME, accountName);
args.putString(EXTRA_TITLE, title);
args.putString(EXTRA_DESCRIPTION, description);
@@ -180,21 +166,22 @@
public View onCreateView(
LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
- mRootView =
- inflater.inflate(
- R.layout.fast_pair_device_pairing_fragment, container, /* attachToRoot= */
- false);
+ /* attachToRoot= */
+ View rootView = inflater.inflate(
+ R.layout.fast_pair_device_pairing_fragment, container, /* attachToRoot= */
+ false);
if (getContext() == null) {
- Log.d("DevicePairingFragment", "can't find the attached activity");
- return mRootView;
+ Log.d(TAG, "can't find the attached activity");
+ return rootView;
}
+
Bundle args = getArguments();
byte[] storeFastPairItemBytesArray = args.getByteArray(EXTRA_HALF_SHEET_INFO);
- boolean isRetroactive = args.getBoolean(EXTRA_HALF_SHEET_IS_RETROACTIVE);
- mIsSubsequentPair = args.getBoolean(EXTRA_HALF_SHEET_IS_SUBSEQUENT_PAIR);
- mIsPairingResurface = args.getBoolean(EXTRA_HALF_SHEET_PAIRING_RESURFACE);
- String accountName = args.getString(EXTRA_HALF_SHEET_ACCOUNT_NAME);
mBundle = args.getBundle(EXTRA_BUNDLE);
+ if (mBundle != null) {
+ mFastPairClient = new FastPairClient(getContext(), mBundle.getBinder(EXTRA_BINDER));
+ mFastPairClient.registerHalfSheet(this);
+ }
if (args.containsKey(ARG_FRAGMENT_STATE)) {
mFragmentState = (HalfSheetFragmentState) args.getSerializable(ARG_FRAGMENT_STATE);
}
@@ -202,86 +189,53 @@
mSetupButtonClicked = args.getBoolean(ARG_SETUP_BUTTON_CLICKED);
}
if (args.containsKey(ARG_PAIRING_RESULT)) {
- mPairingResult = args.getBoolean(ARG_PAIRING_RESULT);
- } else {
- mPairingResult = false;
+ mPairStatus = args.getInt(ARG_PAIRING_RESULT);
}
- // title = ((FragmentActivity) getContext()).findViewById(R.id.toolbar_title);
- mConnectButton = mRootView.findViewById(R.id.connect_btn);
- mImage = mRootView.findViewById(R.id.pairing_pic);
+ // Initiate views.
+ mTitleView = Objects.requireNonNull(getActivity()).findViewById(R.id.toolbar_title);
+ mSubTitleView = rootView.findViewById(R.id.header_subtitle);
+ mImage = rootView.findViewById(R.id.pairing_pic);
+ mConnectProgressBar = rootView.findViewById(R.id.connect_progressbar);
+ mConnectButton = rootView.findViewById(R.id.connect_btn);
+ mCancelButton = rootView.findViewById(R.id.cancel_btn);
+ mSettingsButton = rootView.findViewById(R.id.settings_btn);
+ mSetupButton = rootView.findViewById(R.id.setup_btn);
+ mInfoIconButton = rootView.findViewById(R.id.info_icon);
+ mInfoIconButton.setImageResource(R.drawable.fast_pair_ic_info);
- mConnectProgressBar = mRootView.findViewById(R.id.connect_progressbar);
- mConnectProgressBar.setVisibility(View.INVISIBLE);
+ try {
+ setScanFastPairStoreItem(ScanFastPairStoreItem.parseFrom(storeFastPairItemBytesArray));
+ } catch (InvalidProtocolBufferException e) {
+ Log.w(TAG,
+ "DevicePairingFragment: error happens when pass info to half sheet");
+ return rootView;
+ }
+ // Config for landscape mode
DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
- mRootView.getLayoutParams().height = displayMetrics.heightPixels * 4 / 5;
- mRootView.getLayoutParams().width = displayMetrics.heightPixels * 4 / 5;
+ rootView.getLayoutParams().height = displayMetrics.heightPixels * 4 / 5;
+ rootView.getLayoutParams().width = displayMetrics.heightPixels * 4 / 5;
mImage.getLayoutParams().height = displayMetrics.heightPixels / 2;
mImage.getLayoutParams().width = displayMetrics.heightPixels / 2;
mConnectProgressBar.getLayoutParams().width = displayMetrics.heightPixels / 2;
mConnectButton.getLayoutParams().width = displayMetrics.heightPixels / 2;
+ //TODO(b/213373051): Add cancel button
}
- mCancelButton = mRootView.findViewById(R.id.cancel_btn);
- mSetupButton = mRootView.findViewById(R.id.setup_btn);
- mInfoIconButton = mRootView.findViewById(R.id.info_icon);
- mSubTitle = mRootView.findViewById(R.id.header_subtitle);
- mSetupButton.setVisibility(View.GONE);
- mInfoIconButton.setVisibility(View.GONE);
-
- try {
- if (storeFastPairItemBytesArray != null) {
- mScanFastPairStoreItem =
- ScanFastPairStoreItem.parseFrom(storeFastPairItemBytesArray);
- }
-
- // If the fragmentState is not NOT_STARTED, it is because the fragment was just
- // resumed from
- // configuration change (e.g. rotating the screen or half-sheet resurface). Let's
- // recover the
- // UI directly.
- if (mFragmentState != NOT_STARTED) {
- switch (mFragmentState) {
- case PAIRING:
- Log.d("DevicePairingFragment", "redraw for PAIRING state.");
- return mRootView;
- case RESULT_SUCCESS:
- Log.d("DevicePairingFragment", "redraw for RESULT_SUCCESS state.");
- return mRootView;
- case RESULT_FAILURE:
- Log.d("DevicePairingFragment", "redraw for RESULT_FAILURE state.");
- return mRootView;
- default:
- // fall-out
- Log.d("DevicePairingFragment",
- "DevicePairingFragment: not supported state");
- }
- }
- if (mIsPairingResurface) {
- // Since the Settings contextual card has sent the pairing intent, we don't send the
- // pairing intent here.
- onConnectClick(/* sendPairingIntent= */ false);
- } else {
- mSubTitle.setText(this.getArguments().getString(EXTRA_DESCRIPTION));
- mSubTitle.setText("");
- mConnectButton.setOnClickListener(
- v -> onConnectClick(/* sendPairingIntent= */ true));
- // Pairing fail half sheet resurface
- if (this.getArguments().getString(EXTRA_HALF_SHEET_CONTENT).equals(RESULT_FAIL)) {
- mFragmentState = RESULT_FAILURE;
- showFailInfo();
- } else {
- mConnectButton.setOnClickListener(
- v -> onConnectClick(/* sendPairingIntent= */ true));
- }
- }
- } catch (InvalidProtocolBufferException e) {
- Log.w("DevicePairingFragment",
- "DevicePairingFragment: error happens when pass info to half sheet");
+ Bitmap icon = IconUtils.getIcon(mScanFastPairStoreItem.getIconPng().toByteArray(),
+ mScanFastPairStoreItem.getIconPng().size());
+ if (icon != null) {
+ mImage.setImageBitmap(icon);
}
- return mRootView;
+ mConnectButton.setOnClickListener(v -> onConnectClick());
+ mCancelButton.setOnClickListener(v ->
+ ((HalfSheetActivity) getActivity()).onCancelClicked());
+ mSettingsButton.setOnClickListener(v -> onSettingsClicked());
+ mSetupButton.setOnClickListener(v -> onSetupClick());
+
+ return rootView;
}
@Override
@@ -294,19 +248,8 @@
@Override
public void onStart() {
super.onStart();
- if (getContext() != null) {
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(ACTION_HALF_SHEET_STATUS_CHANGE);
- BroadcastUtils.registerReceiver(getContext(), mHalfSheetChangeReceiver, intentFilter);
- }
- }
-
- @Override
- public void onStop() {
- super.onStop();
- if (getContext() != null) {
- BroadcastUtils.unregisterReceiver(getContext(), mHalfSheetChangeReceiver);
- }
+ Log.v(TAG, "onStart: invalidate states");
+ invalidateState();
}
@Override
@@ -315,118 +258,229 @@
savedInstanceState.putSerializable(ARG_FRAGMENT_STATE, mFragmentState);
savedInstanceState.putBoolean(ARG_SETUP_BUTTON_CLICKED, mSetupButtonClicked);
- savedInstanceState.putBoolean(ARG_PAIRING_RESULT, mPairingResult);
-
-
+ savedInstanceState.putInt(ARG_PAIRING_RESULT, mPairStatus);
}
- @Nullable
- private Intent createCompletionIntent(@Nullable String companionApp, @Nullable String address) {
- if (isEmpty(companionApp)) {
- return null;
- } else if (FastPairUtils.isAppInstalled(getContext(), companionApp)
- && isLaunchable(companionApp)) {
- mOpenCompanionAppIntent = createCompanionAppIntent(companionApp, address);
- return mOpenCompanionAppIntent;
- } else {
- return null;
- }
- }
-
- @Nullable
- private Intent createCompanionAppIntent(String packageName, @Nullable String address) {
- return createCompanionAppIntent(getContext(), packageName, address);
- }
-
- @Nullable
- private static Intent createCompanionAppIntent(
- Context context, String packageName, @Nullable String address) {
- Intent intent = context.getPackageManager().getLaunchIntentForPackage(packageName);
- BluetoothManager manager = context.getSystemService(BluetoothManager.class);
- if (address != null && manager != null) {
- BluetoothAdapter adapter = manager.getAdapter();
- if (intent != null && adapter != null) {
- intent.putExtra(BluetoothDevice.EXTRA_DEVICE, adapter.getRemoteDevice(address));
- }
- }
- return intent;
- }
-
- private void onConnectClick(boolean sendPairingIntent) {
- if (mScanFastPairStoreItem == null) {
- Log.w("DevicePairingFragment", "No pairing related information in half sheet");
- return;
- }
-
- Log.d("FastPairHalfSheet", "on connect click");
- // Allow user to setup device before connection setup.
- // showPairingLastPhase();
- ((Activity) getContext())
- .findViewById(R.id.background)
- .setOnClickListener(
- v ->
- Log.d("DevicePairingFragment",
- "DevicePairingFragment: tap empty area do not dismiss "
- + "half sheet when pairing."));
- if (sendPairingIntent) {
- try {
- Log.d("FastPairHalfSheet", "on connect click");
- Intent intent =
- new Intent(ACTION_FAST_PAIR)
- // Using the DiscoveryChimeraService notification id for
- // backwards compat
- .putExtra(
- UserActionHandler.EXTRA_DISCOVERY_ITEM,
- FastPairUtils.convertFrom(
- mScanFastPairStoreItem).toByteArray())
- .putExtra(EXTRA_MODEL_ID, mScanFastPairStoreItem.getModelId())
- .putExtra(EXTRA_PRIVATE_BLE_ADDRESS,
- mScanFastPairStoreItem.getAddress());
- IFastPairHalfSheetCallback.Stub.asInterface(mBundle.getBinder(EXTRA_BINDER))
- .onHalfSheetConnectionConfirm(intent);
- } catch (RemoteException e) {
- Log.d("FastPairHalfSheet", "invoke callback fall");
- }
- }
- }
-
- private void onFailConnectClick() {
+ private void onSettingsClicked() {
startActivity(new Intent(Settings.ACTION_BLUETOOTH_SETTINGS));
}
- private final BroadcastReceiver mHalfSheetChangeReceiver =
- new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (!ACTION_HALF_SHEET_STATUS_CHANGE.equals(intent.getAction())) {
- return;
- }
- if (SUCCESS_STATE.equals(intent.getStringExtra(FINISHED_STATE))) {
- mBluetoothMacAddress = intent.getStringExtra(EXTRA_CLASSIC_MAC_ADDRESS);
- showSuccessInfo();
- if (mOpenCompanionAppIntent != null) {
- //((HalfSheetActivity) getContext()).halfSheetStateChange();
- String companionApp =
- FastPairUtils.getCompanionAppFromActionUrl(
- mScanFastPairStoreItem.getActionUrl());
- // Redirect user to companion app if user choose to setup the app.
- // Recreate the intent
- // since the correct mac address just populated.
- startActivity(
- createCompletionIntent(companionApp, mBluetoothMacAddress));
- }
- } else if (FAIL_STATE.equals(intent.getStringExtra(FINISHED_STATE))) {
- showFailInfo();
- } else if (DISMISS.equals(intent.getStringExtra(FINISHED_STATE))) {
- if (getContext() != null) {
- HalfSheetActivity activity = (HalfSheetActivity) getContext();
- activity.finish();
- }
- }
- }
- };
+ private void onSetupClick() {
+ String companionApp =
+ FastPairUtils.getCompanionAppFromActionUrl(mScanFastPairStoreItem.getActionUrl());
+ Intent intent =
+ FastPairUtils.createCompanionAppIntent(
+ Objects.requireNonNull(getContext()),
+ companionApp,
+ mScanFastPairStoreItem.getAddress());
+ mSetupButtonClicked = true;
+ if (mFragmentState == PAIRED_LAUNCHABLE) {
+ if (intent != null) {
+ startActivity(intent);
+ }
+ } else {
+ Log.d(TAG, "onSetupClick: State is " + mFragmentState);
+ }
+ }
- private boolean isLaunchable(String companionApp) {
- return createCompanionAppIntent(companionApp, null) != null;
+ private void onConnectClick() {
+ if (mScanFastPairStoreItem == null) {
+ Log.w(TAG, "No pairing related information in half sheet");
+ return;
+ }
+ if (getFragmentState() == PAIRING) {
+ return;
+ }
+ mIsConnecting = true;
+ invalidateState();
+ mFastPairClient.connect(
+ new FastPairDevice.Builder()
+ .addMedium(NearbyDevice.Medium.BLE)
+ .setBluetoothAddress(mScanFastPairStoreItem.getAddress())
+ .setData(FastPairUtils.convertFrom(mScanFastPairStoreItem)
+ .toByteArray())
+ .build());
+ }
+
+ // Receives callback from service.
+ @Override
+ public void onPairUpdate(FastPairDevice fastPairDevice, PairStatusMetadata pairStatusMetadata) {
+ @PairStatusMetadata.Status int status = pairStatusMetadata.getStatus();
+ if (status == PairStatusMetadata.Status.DISMISS && getActivity() != null) {
+ getActivity().finish();
+ }
+ mIsConnecting = false;
+ mPairStatus = status;
+ invalidateState();
+ }
+
+ @Override
+ public void invalidateState() {
+ HalfSheetFragmentState newState = NOT_STARTED;
+ if (mIsConnecting) {
+ newState = PAIRING;
+ } else {
+ switch (mPairStatus) {
+ case PairStatusMetadata.Status.SUCCESS:
+ newState = mIsLaunchable ? PAIRED_LAUNCHABLE : PAIRED_UNLAUNCHABLE;
+ break;
+ case PairStatusMetadata.Status.FAIL:
+ newState = FAILED;
+ break;
+ default:
+ if (mScanFastPairStoreItem != null) {
+ newState = FOUND_DEVICE;
+ }
+ }
+ }
+ if (newState == mFragmentState) {
+ return;
+ }
+ setState(newState);
+ }
+
+ @Override
+ public void setState(HalfSheetFragmentState state) {
+ super.setState(state);
+ invalidateTitles();
+ invalidateButtons();
+ }
+
+ private void setScanFastPairStoreItem(ScanFastPairStoreItem item) {
+ mScanFastPairStoreItem = item;
+ invalidateLaunchable();
+ }
+
+ private void invalidateLaunchable() {
+ String companionApp =
+ FastPairUtils.getCompanionAppFromActionUrl(mScanFastPairStoreItem.getActionUrl());
+ if (isEmpty(companionApp)) {
+ mIsLaunchable = false;
+ return;
+ }
+ mIsLaunchable =
+ FastPairUtils.isLaunchable(Objects.requireNonNull(getContext()), companionApp);
+ }
+
+ private void invalidateButtons() {
+ mConnectProgressBar.setVisibility(View.INVISIBLE);
+ mConnectButton.setVisibility(View.INVISIBLE);
+ mCancelButton.setVisibility(View.INVISIBLE);
+ mSetupButton.setVisibility(View.INVISIBLE);
+ mSettingsButton.setVisibility(View.INVISIBLE);
+ mInfoIconButton.setVisibility(View.INVISIBLE);
+
+ switch (mFragmentState) {
+ case FOUND_DEVICE:
+ mInfoIconButton.setVisibility(View.VISIBLE);
+ mConnectButton.setVisibility(View.VISIBLE);
+ break;
+ case PAIRING:
+ mConnectProgressBar.setVisibility(View.VISIBLE);
+ mCancelButton.setVisibility(View.VISIBLE);
+ setBackgroundClickable(false);
+ break;
+ case PAIRED_LAUNCHABLE:
+ mCancelButton.setVisibility(View.VISIBLE);
+ mSetupButton.setVisibility(View.VISIBLE);
+ setBackgroundClickable(true);
+ break;
+ case FAILED:
+ mSettingsButton.setVisibility(View.VISIBLE);
+ setBackgroundClickable(true);
+ break;
+ case NOT_STARTED:
+ case PAIRED_UNLAUNCHABLE:
+ default:
+ mCancelButton.setVisibility(View.VISIBLE);
+ setBackgroundClickable(true);
+ }
+ }
+
+ private void setBackgroundClickable(boolean isClickable) {
+ HalfSheetActivity activity = (HalfSheetActivity) getActivity();
+ if (activity == null) {
+ Log.w(TAG, "setBackgroundClickable: failed to set clickable to " + isClickable
+ + " because cannot get HalfSheetActivity.");
+ return;
+ }
+ View background = activity.findViewById(R.id.background);
+ if (background == null) {
+ Log.w(TAG, "setBackgroundClickable: failed to set clickable to " + isClickable
+ + " cannot find background at HalfSheetActivity.");
+ return;
+ }
+ Log.d(TAG, "setBackgroundClickable to " + isClickable);
+ background.setClickable(isClickable);
+ }
+
+ private void invalidateTitles() {
+ String newTitle = getTitle();
+ invalidateTextView(mTitleView, newTitle);
+ String newSubTitle = getSubTitle();
+ invalidateTextView(mSubTitleView, newSubTitle);
+ }
+
+ private void invalidateTextView(TextView textView, String newText) {
+ CharSequence oldText =
+ textView.getTag(TAG_PENDING_TEXT) != null
+ ? (CharSequence) textView.getTag(TAG_PENDING_TEXT)
+ : textView.getText();
+ if (TextUtils.equals(oldText, newText)) {
+ return;
+ }
+ if (TextUtils.isEmpty(oldText)) {
+ // First time run. Don't animate since there's nothing to animate from.
+ textView.setText(newText);
+ } else {
+ textView.setTag(TAG_PENDING_TEXT, newText);
+ textView
+ .animate()
+ .alpha(0f)
+ .setDuration(TEXT_ANIMATION_DURATION_MILLISECONDS)
+ .withEndAction(
+ () -> {
+ textView.setText(newText);
+ textView
+ .animate()
+ .alpha(1f)
+ .setDuration(TEXT_ANIMATION_DURATION_MILLISECONDS);
+ });
+ }
+ }
+
+ private String getTitle() {
+ switch (mFragmentState) {
+ case PAIRED_LAUNCHABLE:
+ return getString(R.string.fast_pair_title_setup);
+ case FAILED:
+ return getString(R.string.fast_pair_title_fail);
+ case FOUND_DEVICE:
+ case NOT_STARTED:
+ case PAIRED_UNLAUNCHABLE:
+ default:
+ return mScanFastPairStoreItem.getDeviceName();
+ }
+ }
+
+ private String getSubTitle() {
+ switch (mFragmentState) {
+ case PAIRED_LAUNCHABLE:
+ return String.format(
+ mScanFastPairStoreItem
+ .getFastPairStrings()
+ .getPairingFinishedCompanionAppInstalled(),
+ mScanFastPairStoreItem.getDeviceName());
+ case FAILED:
+ return mScanFastPairStoreItem.getFastPairStrings().getPairingFailDescription();
+ case PAIRED_UNLAUNCHABLE:
+ getString(R.string.fast_pair_device_ready);
+ // fall through
+ case FOUND_DEVICE:
+ case NOT_STARTED:
+ return mScanFastPairStoreItem.getFastPairStrings().getInitialPairingDescription();
+ default:
+ return "";
+ }
}
}
diff --git a/nearby/halfsheet/src/com/android/nearby/halfsheet/fragment/HalfSheetModuleFragment.java b/nearby/halfsheet/src/com/android/nearby/halfsheet/fragment/HalfSheetModuleFragment.java
index 88caf95..f1db4d0 100644
--- a/nearby/halfsheet/src/com/android/nearby/halfsheet/fragment/HalfSheetModuleFragment.java
+++ b/nearby/halfsheet/src/com/android/nearby/halfsheet/fragment/HalfSheetModuleFragment.java
@@ -15,17 +15,23 @@
*/
package com.android.nearby.halfsheet.fragment;
+import static com.android.nearby.halfsheet.HalfSheetActivity.TAG;
+import static com.android.nearby.halfsheet.fragment.HalfSheetModuleFragment.HalfSheetFragmentState.NOT_STARTED;
+
import android.os.Bundle;
+import android.util.Log;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
/** Base class for all of the half sheet fragment. */
-// TODO(b/177675274): Resolve nullness suppression.
-@SuppressWarnings("nullness")
public abstract class HalfSheetModuleFragment extends Fragment {
+ static final int TEXT_ANIMATION_DURATION_MILLISECONDS = 200;
+
+ HalfSheetFragmentState mFragmentState = NOT_STARTED;
+
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -38,26 +44,15 @@
/** UI states of the half-sheet fragment. */
public enum HalfSheetFragmentState {
- NOT_STARTED,
- SYNC_CONTACTS,
- SYNC_SMS,
- PROGRESSING,
- CONFIRM_PASSKEY,
- WRONG_PASSKEY,
- PAIRING,
- ADDITIONAL_SETUP_PROGRESS,
- ADDITIONAL_SETUP_FINAL,
- RESULT_SUCCESS,
- RESULT_FAILURE,
- FINISHED
- }
-
- /** Only used in {@link DevicePairingFragment} show pairing success info in half sheet. */
- public void showSuccessInfo() {
- }
-
- /** Only used in {@link DevicePairingFragment} show pairing fail info in half sheet. */
- public void showFailInfo() {
+ NOT_STARTED, // Initial status
+ FOUND_DEVICE, // When a device is found found from Nearby scan service
+ PAIRING, // When user taps 'Connect' and Fast Pair stars pairing process
+ PAIRED_LAUNCHABLE, // When pair successfully
+ // and we found a launchable companion app installed
+ PAIRED_UNLAUNCHABLE, // When pair successfully
+ // but we cannot find a companion app to launch it
+ FAILED, // When paring was failed
+ FINISHED // When the activity is about to end finished.
}
/**
@@ -67,6 +62,16 @@
* activity.
*/
public HalfSheetFragmentState getFragmentState() {
- return HalfSheetFragmentState.NOT_STARTED;
+ return mFragmentState;
}
+
+ void setState(HalfSheetFragmentState state) {
+ Log.v(TAG, "Settings state from " + mFragmentState + " to " + state);
+ mFragmentState = state;
+ }
+
+ /**
+ * Populate data to UI widgets according to the latest {@link HalfSheetFragmentState}.
+ */
+ abstract void invalidateState();
}
diff --git a/nearby/halfsheet/src/com/android/nearby/halfsheet/utils/BroadcastUtils.java b/nearby/halfsheet/src/com/android/nearby/halfsheet/utils/BroadcastUtils.java
index cae2d8e..467997c 100644
--- a/nearby/halfsheet/src/com/android/nearby/halfsheet/utils/BroadcastUtils.java
+++ b/nearby/halfsheet/src/com/android/nearby/halfsheet/utils/BroadcastUtils.java
@@ -16,30 +16,13 @@
package com.android.nearby.halfsheet.utils;
-
-import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
/**
* Broadcast util class
*/
public class BroadcastUtils {
- /**
- * Registers a list of broadcast receiver.
- */
- public static void registerReceiver(
- Context context, BroadcastReceiver receiver, IntentFilter intentFilter) {
- context.registerReceiver(receiver, intentFilter);
- }
-
- /**
- * Unregisters the already registered receiver.
- */
- public static void unregisterReceiver(Context context, BroadcastReceiver receiver) {
- context.unregisterReceiver(receiver);
- }
/**
* Helps send broadcast.
diff --git a/nearby/halfsheet/src/com/android/nearby/halfsheet/utils/FastPairUtils.java b/nearby/halfsheet/src/com/android/nearby/halfsheet/utils/FastPairUtils.java
index fffb9e1..903ea90 100644
--- a/nearby/halfsheet/src/com/android/nearby/halfsheet/utils/FastPairUtils.java
+++ b/nearby/halfsheet/src/com/android/nearby/halfsheet/utils/FastPairUtils.java
@@ -38,8 +38,6 @@
*/
public class FastPairUtils {
- public static final String TAG = "HalfSheetActivity";
-
/** FastPair util method check certain app is install on the device or not. */
public static boolean isAppInstalled(Context context, String packageName) {
try {
diff --git a/nearby/halfsheet/src/com/android/nearby/halfsheet/utils/IconUtils.java b/nearby/halfsheet/src/com/android/nearby/halfsheet/utils/IconUtils.java
index 0521b7b..218c756 100644
--- a/nearby/halfsheet/src/com/android/nearby/halfsheet/utils/IconUtils.java
+++ b/nearby/halfsheet/src/com/android/nearby/halfsheet/utils/IconUtils.java
@@ -16,7 +16,7 @@
package com.android.nearby.halfsheet.utils;
-import static com.android.nearby.halfsheet.utils.FastPairUtils.TAG;
+import static com.android.nearby.halfsheet.HalfSheetActivity.TAG;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;