[Wi-Fi] Add basic UI structure for adding Wi-Fi for apps feature.

Add following changes:
1. Add intent receiver.
2. Add panel UI with icon, title, summary.
3. Add two buttons (save and cancel).
4. Add test case for activity and fragment

Bug: 136472483
Test: Add following test cases for checking button and package name in activity and fragment.
      1. AddAppNetworksActivityTest
      2. AddAppNetworksFragmentTest
Change-Id: I5515a96fa3feb0e3e6d68159b2c0dec0894c15ee
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index c2dcd15..4cdfa25 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -3053,6 +3053,18 @@
                 </intent-filter>
         </activity>
 
+        <activity android:name=".wifi.addappnetworks.AddAppNetworksActivity"
+                  android:label="@string/settings_panel_title"
+                  android:theme="@style/Theme.Panel"
+                  android:launchMode="singleInstance"
+                  android:excludeFromRecents="true"
+                  android:permission="android.permission.CHANGE_WIFI_STATE">
+            <intent-filter>
+                <action android:name="android.settings.WIFI_ADD_NETWORKS" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
         <activity-alias
             android:name="MediaOutputSlice"
             android:label="@string/media_output_panel_title"
diff --git a/res/layout/wifi_add_app_networks.xml b/res/layout/wifi_add_app_networks.xml
new file mode 100644
index 0000000..2dc3993
--- /dev/null
+++ b/res/layout/wifi_add_app_networks.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2019 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
+  -->
+
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/panel_container"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@drawable/settings_panel_background">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:gravity="start|center_vertical"
+            android:clipToPadding="false"
+            android:paddingStart="12dp"
+            android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
+
+            <LinearLayout
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:gravity="start|center_vertical"
+                android:minWidth="68dp"
+                android:orientation="horizontal"
+                android:clipToPadding="false"
+                android:paddingTop="4dp"
+                android:paddingBottom="4dp">
+                <androidx.preference.internal.PreferenceImageView
+                    android:id="@+id/app_icon"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center"
+                    settings:maxWidth="48dp"
+                    settings:maxHeight="48dp"/>
+            </LinearLayout>
+
+            <RelativeLayout
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:paddingTop="16dp"
+                android:paddingBottom="16dp">
+
+                <TextView
+                    android:id="@+id/app_title"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:singleLine="true"
+                    android:textAppearance="?android:attr/textAppearanceListItem"
+                    android:ellipsize="marquee"/>
+
+                <TextView
+                    android:id="@+id/app_summary"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_below="@+id/app_title"
+                    android:layout_alignStart="@+id/app_title"
+                    android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+                    android:textColor="?android:attr/textColorSecondary"
+                    android:maxLines="10"/>
+            </RelativeLayout>
+        </LinearLayout>
+
+        <include layout="@layout/horizontal_divider"/>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:paddingTop="8dp"
+            android:paddingBottom="8dp">
+
+            <Button
+                android:id="@+id/cancel"
+                style="@android:style/Widget.DeviceDefault.Button.Borderless.Colored"
+                android:layout_width="wrap_content"
+                android:layout_height="48dp"
+                android:layout_marginStart="12dp"
+                android:text="@string/cancel"/>
+
+            <Space
+                android:layout_weight="1"
+                android:layout_width="0dp"
+                android:layout_height="match_parent"/>
+
+            <Button
+                android:id="@+id/save"
+                style="@android:style/Widget.DeviceDefault.Button.Borderless.Colored"
+                android:layout_width="wrap_content"
+                android:layout_height="48dp"
+                android:layout_marginEnd="12dp"
+                android:text="@string/save"/>
+        </LinearLayout>
+    </LinearLayout>
+</FrameLayout>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 4242609..50cecfa 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2338,6 +2338,10 @@
     <string name="wifi_hotspot_configure_ap_text_summary">AndroidAP WPA2 PSK hotspot</string>
     <!-- Default access point SSID used for tethering -->
     <string name="wifi_tether_configure_ssid_default">AndroidHotspot</string>
+    <!-- Title for the panel of add Wi-Fi network from APP [CHAR LIMIT=50]-->
+    <string name="wifi_add_app_single_network_title">Save this network?</string>
+    <!-- Summary for the panel of add Wi-Fi network from APP [CHAR LIMIT=NONE]-->
+    <string name="wifi_add_app_single_network_summary"><xliff:g id="appName" example="ThirdPartyAppName">%1$s</xliff:g> would like to save a network to your phone</string>
 
     <!-- Do not translate. Used for diagnostic screens, precise translation is not necessary
          Wi-Fi Testing on the diagnostic screen-->
diff --git a/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivity.java b/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivity.java
new file mode 100644
index 0000000..0810b54
--- /dev/null
+++ b/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivity.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2019 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.android.settings.wifi.addappnetworks;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.Gravity;
+import android.view.Window;
+import android.view.WindowManager;
+
+import androidx.annotation.Nullable;
+import androidx.fragment.app.FragmentActivity;
+import androidx.fragment.app.FragmentManager;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.settings.R;
+import com.android.settings.core.HideNonSystemOverlayMixin;
+
+/**
+ * When apps send a new intent with a WifiConfiguration list extra to Settings APP. Settings APP
+ * will launch this activity, which contains {@code AddAppNetworksFragment}, with a UI panel pop
+ * up asking the user if they approve the network being proposed by the app to be saved on to
+ * the device. User can decide to save or cancel the request.,
+ */
+public class AddAppNetworksActivity extends FragmentActivity {
+    public static final String TAG = "AddAppNetworksActivity";
+
+    private AddAppNetworksFragment mFragment;
+
+    /** Key specifying the package name of the apps which requested the Panel. */
+    public static final String KEY_CALLING_PACKAGE_NAME = "panel_calling_package_name";
+
+    @VisibleForTesting
+    final Bundle mBundle = new Bundle();
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.settings_panel);
+        showAddNetworksFragment();
+        getLifecycle().addObserver(new HideNonSystemOverlayMixin(this));
+    }
+
+    @Override
+    protected void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+        setIntent(intent);
+        showAddNetworksFragment();
+    }
+
+    @VisibleForTesting
+    void showAddNetworksFragment() {
+        // Move the window to the bottom of screen, and make it take up the entire screen width.
+        final Window window = getWindow();
+        window.setGravity(Gravity.BOTTOM);
+        window.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
+                WindowManager.LayoutParams.WRAP_CONTENT);
+
+        // TODO: check the new intent status
+        mBundle.putString(KEY_CALLING_PACKAGE_NAME, getCallingPackage());
+        final FragmentManager fragmentManager = getSupportFragmentManager();
+        if (fragmentManager.findFragmentByTag(TAG) == null) {
+            final AddAppNetworksFragment fragment = new AddAppNetworksFragment();
+            fragment.setArguments(mBundle);
+            fragmentManager.beginTransaction().add(R.id.main_content, fragment, TAG).commit();
+        }
+    }
+}
diff --git a/src/com/android/settings/wifi/addappnetworks/AddAppNetworksFragment.java b/src/com/android/settings/wifi/addappnetworks/AddAppNetworksFragment.java
new file mode 100644
index 0000000..281ca57
--- /dev/null
+++ b/src/com/android/settings/wifi/addappnetworks/AddAppNetworksFragment.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2019 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.android.settings.wifi.addappnetworks;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.FragmentActivity;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settings.core.InstrumentedFragment;
+
+import java.util.ArrayList;
+
+/**
+ * The Fragment list those networks, which is proposed by other app, to user, and handle user's
+ * choose on either saving those networks or rejecting the request.
+ */
+public class AddAppNetworksFragment extends InstrumentedFragment {
+    public static final String TAG = "AddAppNetworksFragment";
+
+    private TextView mTitleView;
+    private TextView mSummaryView;
+    private ImageView mIconView;
+
+    @VisibleForTesting
+    Button mCancelButton;
+    @VisibleForTesting
+    Button mSaveButton;
+    @VisibleForTesting
+    String mCallingPackageName;
+
+    @Nullable
+    @Override
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
+            @Nullable Bundle savedInstanceState) {
+        return inflater.inflate(R.layout.wifi_add_app_networks, container, false);
+    }
+
+    @Override
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+
+        // init local variable.
+        mTitleView = view.findViewById(R.id.app_title);
+        mIconView = view.findViewById(R.id.app_icon);
+        mCancelButton = view.findViewById(R.id.cancel);
+        mSaveButton = view.findViewById(R.id.save);
+        mSummaryView = view.findViewById(R.id.app_summary);
+
+        // Assigns button listeners.
+        mCancelButton.setOnClickListener(getCancelListener());
+        mSaveButton.setOnClickListener(getSaveListener());
+
+        final Bundle bundle = getArguments();
+        createContent(bundle);
+    }
+
+    private void createContent(Bundle bundle) {
+        final FragmentActivity activity = getActivity();
+
+        // Assigns caller app icon and summary.
+        mCallingPackageName =
+                bundle.getString(AddAppNetworksActivity.KEY_CALLING_PACKAGE_NAME);
+        assignAppIcon(activity, mCallingPackageName);
+        assignTitleAndSummary(activity, mCallingPackageName);
+    }
+
+    private void assignAppIcon(Context context, String callingPackageName) {
+        final Drawable drawable = loadPackageIconDrawable(context, callingPackageName);
+        mIconView.setImageDrawable(drawable);
+    }
+
+    private Drawable loadPackageIconDrawable(Context context, String callingPackageName) {
+        Drawable icon = null;
+        try {
+            icon = context.getPackageManager().getApplicationIcon(callingPackageName);
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.d(TAG, "Cannot get application icon", e);
+        }
+
+        return icon;
+    }
+
+    private void assignTitleAndSummary(Context context, String callingPackageName) {
+        // Assigns caller app name to title
+        mTitleView.setText(getTitle());
+
+        // Set summary
+        mSummaryView.setText(getAddNetworkRequesterSummary(
+                Utils.getApplicationLabel(context, callingPackageName)));
+    }
+
+    private CharSequence getAddNetworkRequesterSummary(CharSequence appName) {
+        return getString(R.string.wifi_add_app_single_network_summary, appName);
+    }
+
+    private CharSequence getTitle() {
+        return getString(R.string.wifi_add_app_single_network_title);
+    }
+
+    View.OnClickListener getCancelListener() {
+        return (v) -> {
+            Log.d(TAG, "User rejected to add network");
+        };
+    }
+
+    View.OnClickListener getSaveListener() {
+        return (v) -> {
+            Log.d(TAG, "User agree to add networks");
+        };
+    }
+
+    private void finishWithResult(int resultCode, ArrayList<Integer> resultArrayList) {
+        if (resultArrayList != null) {
+            Intent intent = new Intent();
+            intent.putIntegerArrayListExtra(Settings.EXTRA_WIFI_CONFIGURATION_RESULT_LIST,
+                    resultArrayList);
+            getActivity().setResult(resultCode, intent);
+        }
+        getActivity().finish();
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        // TODO(b/144891278): Need to define a new metric for this page, use the WIFI item first.
+        return SettingsEnums.WIFI;
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivityTest.java b/tests/robotests/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivityTest.java
new file mode 100644
index 0000000..b614698
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivityTest.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2019 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.android.settings.wifi.addappnetworks;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.robolectric.Shadows.shadowOf;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class AddAppNetworksActivityTest {
+
+    @Test
+    public void startActivity_withPackageName_bundleShouldHaveRightPackageName() {
+        final String packageName = RuntimeEnvironment.application.getPackageName();
+        final AddAppNetworksActivity activity =
+                Robolectric.buildActivity(AddAppNetworksActivity.class).create().get();
+        shadowOf(activity).setCallingPackage(packageName);
+
+        activity.showAddNetworksFragment();
+
+        assertThat(activity.mBundle.getString(AddAppNetworksActivity.KEY_CALLING_PACKAGE_NAME))
+                .isEqualTo(packageName);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/wifi/addappnetworks/AddAppNetworksFragmentTest.java b/tests/robotests/src/com/android/settings/wifi/addappnetworks/AddAppNetworksFragmentTest.java
new file mode 100644
index 0000000..38ddf33
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/wifi/addappnetworks/AddAppNetworksFragmentTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2019 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.android.settings.wifi.addappnetworks;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+import android.os.Bundle;
+
+import androidx.fragment.app.FragmentActivity;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.shadows.androidx.fragment.FragmentController;
+
+@RunWith(RobolectricTestRunner.class)
+public class AddAppNetworksFragmentTest {
+    private static final String FAKE_APP_NAME = "fake_app_name";
+    private FragmentActivity mActivity;
+    private AddAppNetworksFragment mAddAppNetworksFragment;
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        mAddAppNetworksFragment = spy(new AddAppNetworksFragment());
+        MockitoAnnotations.initMocks(this);
+
+        // Set up bundle
+        final Bundle bundle = new Bundle();
+        bundle.putString(AddAppNetworksActivity.KEY_CALLING_PACKAGE_NAME, FAKE_APP_NAME);
+        doReturn(bundle).when(mAddAppNetworksFragment).getArguments();
+
+        FragmentController.setupFragment(mAddAppNetworksFragment);
+    }
+
+    @Test
+    public void callingPackageName_onCreateView_shouldBeCorrect() {
+        assertThat(mAddAppNetworksFragment.mCallingPackageName).isEqualTo(FAKE_APP_NAME);
+    }
+
+    @Test
+    public void launchFragment_shouldShowSaveButton() {
+        assertThat(mAddAppNetworksFragment.mSaveButton).isNotNull();
+    }
+
+    @Test
+    public void launchFragment_shouldShowCancelButton() {
+        assertThat(mAddAppNetworksFragment.mCancelButton).isNotNull();
+    }
+}