Make package installer a sequence of alert-dialogs.
To make sure the dialog does not change height a single content for all
steps of the sequence. We just unhide the view that should actually be
shown.
Also added a night-mode theme.
Test: Manually uninstalled, installed and update package.
atest CtsNoPermissionTestCases
CtsNoPermissionTestCases25
CtsPackageInstallTestCases
CtsPackageUninstallTestCases
CtsPackageInstallerTapjackingTestCases
Change-Id: I890bb1f2697df3af87b6cb65e460f611334523ee
This commit is contained in:
@@ -19,7 +19,7 @@
|
||||
android:label="@string/app_name"
|
||||
android:icon="@drawable/ic_app_icon"
|
||||
android:allowBackup="false"
|
||||
android:theme="@style/DialogWhenLarge"
|
||||
android:theme="@style/Theme.AlertDialogActivity"
|
||||
android:supportsRtl="true"
|
||||
android:defaultToDeviceProtectedStorage="true"
|
||||
android:directBootAware="true">
|
||||
@@ -32,6 +32,7 @@
|
||||
</receiver>
|
||||
|
||||
<activity android:name=".InstallStart"
|
||||
android:theme="@android:style/Theme.Translucent.NoTitleBar"
|
||||
android:exported="true"
|
||||
android:excludeFromRecents="true">
|
||||
<intent-filter android:priority="1">
|
||||
@@ -59,13 +60,14 @@
|
||||
android:exported="false" />
|
||||
|
||||
<activity android:name=".DeleteStagedFileOnResult"
|
||||
android:theme="@android:style/Theme.Translucent.NoTitleBar"
|
||||
android:exported="false" />
|
||||
|
||||
<activity android:name=".PackageInstallerActivity"
|
||||
android:exported="false" />
|
||||
|
||||
<activity android:name=".InstallInstalling"
|
||||
android:theme="@style/DialogWhenLargeNoAnimation"
|
||||
android:theme="@style/Theme.AlertDialogActivity.NoAnimation"
|
||||
android:exported="false" />
|
||||
|
||||
<receiver android:name=".InstallEventReceiver"
|
||||
@@ -77,18 +79,17 @@
|
||||
</receiver>
|
||||
|
||||
<activity android:name=".InstallSuccess"
|
||||
android:theme="@style/DialogWhenLargeNoAnimation"
|
||||
android:theme="@style/Theme.AlertDialogActivity.NoAnimation"
|
||||
android:exported="false" />
|
||||
|
||||
<activity android:name=".InstallFailed"
|
||||
android:theme="@style/DialogWhenLargeNoAnimation"
|
||||
android:theme="@style/Theme.AlertDialogActivity.NoAnimation"
|
||||
android:exported="false" />
|
||||
|
||||
<activity android:name=".UninstallerActivity"
|
||||
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||
android:excludeFromRecents="true"
|
||||
android:noHistory="true"
|
||||
android:theme="@style/AlertDialogActivity">
|
||||
android:noHistory="true">
|
||||
<intent-filter android:priority="1">
|
||||
<action android:name="android.intent.action.DELETE" />
|
||||
<action android:name="android.intent.action.UNINSTALL_PACKAGE" />
|
||||
@@ -107,7 +108,6 @@
|
||||
|
||||
<activity android:name=".UninstallUninstalling"
|
||||
android:excludeFromRecents="true"
|
||||
android:theme="@style/AlertDialogActivity"
|
||||
android:exported="false" />
|
||||
|
||||
<receiver android:name=".UninstallFinish"
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2016 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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout android:id="@+id/app_snippet"
|
||||
android:background="?android:attr/colorPrimary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?android:attr/actionBarSize"
|
||||
android:orientation="horizontal"
|
||||
android:elevation="@dimen/headerElevation"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<ImageView android:id="@+id/app_icon"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_file_download" />
|
||||
|
||||
<TextView android:id="@+id/app_name"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/titleTextStyle"
|
||||
android:singleLine="true"
|
||||
android:text="@string/app_name_unknown"
|
||||
android:ellipsize="end" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ScrollView android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:padding="16dip">
|
||||
|
||||
<TextView android:id="@+id/install_confirm_question"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
</ScrollView>
|
||||
|
||||
<LinearLayout style="?android:attr/buttonBarStyle"
|
||||
android:background="?android:attr/colorBackground"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:padding="8dp"
|
||||
android:measureWithLargestChild="true">
|
||||
|
||||
<!-- spacer to push buttons to the right -->
|
||||
<View android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<Button android:id="@+id/cancel_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/cancel"
|
||||
android:maxLines="2"
|
||||
style="?android:attr/buttonBarButtonStyle" />
|
||||
|
||||
<Button android:id="@+id/ok_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/install"
|
||||
android:maxLines="2"
|
||||
style="?android:attr/buttonBarButtonStyle" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
144
packages/PackageInstaller/res/layout/install_content_view.xml
Normal file
144
packages/PackageInstaller/res/layout/install_content_view.xml
Normal file
@@ -0,0 +1,144 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="?android:attr/alertDialogTheme"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingLeft="?android:attr/dialogPreferredPadding"
|
||||
android:paddingRight="?android:attr/dialogPreferredPadding">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/staging"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:visibility="invisible">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@android:style/TextAppearance.Material.Subhead"
|
||||
android:text="@string/message_staging" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progress_indeterminate"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="8dp"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:indeterminate="true" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/installing"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:visibility="invisible">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@android:style/TextAppearance.Material.Subhead"
|
||||
android:text="@string/installing" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progress"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="8dp"
|
||||
style="?android:attr/progressBarStyleHorizontal" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/install_confirm_question"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@android:style/TextAppearance.Material.Subhead"
|
||||
android:text="@string/install_confirm_question"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/install_confirm_question_update"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@android:style/TextAppearance.Material.Subhead"
|
||||
android:text="@string/install_confirm_question_update"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/install_confirm_question_update_system"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@android:style/TextAppearance.Material.Subhead"
|
||||
android:text="@string/install_confirm_question_update_system"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/install_success"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@android:style/TextAppearance.Material.Subhead"
|
||||
android:text="@string/install_done"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/install_failed"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@android:style/TextAppearance.Material.Subhead"
|
||||
android:text="@string/install_failed"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/install_failed_blocked"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@android:style/TextAppearance.Material.Subhead"
|
||||
android:text="@string/install_failed_blocked"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/install_failed_conflict"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@android:style/TextAppearance.Material.Subhead"
|
||||
android:text="@string/install_failed_conflict"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/install_failed_incompatible"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@android:style/TextAppearance.Material.Subhead"
|
||||
android:text="@string/install_failed_incompatible"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/install_failed_invalid_apk"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@android:style/TextAppearance.Material.Subhead"
|
||||
android:text="@string/install_failed_invalid_apk"
|
||||
android:visibility="invisible" />
|
||||
|
||||
</FrameLayout>
|
||||
@@ -1,96 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2016 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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout android:id="@+id/app_snippet"
|
||||
android:background="?android:attr/colorPrimary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?android:attr/actionBarSize"
|
||||
android:orientation="horizontal"
|
||||
android:elevation="@dimen/headerElevation"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<ImageView android:id="@+id/app_icon"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:scaleType="fitCenter" />
|
||||
|
||||
<TextView android:id="@+id/app_name"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/titleTextStyle"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout android:id="@+id/simple_status_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="16dip"
|
||||
android:paddingRight="16dip">
|
||||
|
||||
<ImageView android:id="@+id/center_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:src="@drawable/ic_report_problem_92"
|
||||
android:tint="@color/bigIconColor"
|
||||
android:contentDescription="@null" />
|
||||
|
||||
<TextView android:id="@+id/simple_status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout android:id="@+id/buttons_panel"
|
||||
style="?android:attr/buttonBarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:measureWithLargestChild="true"
|
||||
android:padding="8dip">
|
||||
|
||||
<!-- spacer to push button to the right -->
|
||||
<View android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<Button android:id="@+id/done_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/done"
|
||||
android:maxLines="2"
|
||||
style="?android:attr/buttonBarButtonStyle" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!-- Copyright (C) 2016 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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout android:id="@+id/app_snippet"
|
||||
android:background="?android:attr/colorPrimary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?android:attr/actionBarSize"
|
||||
android:orientation="horizontal"
|
||||
android:elevation="@dimen/headerElevation"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/app_icon"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:scaleType="fitCenter" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/app_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:attr/titleTextStyle" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="16dip"
|
||||
android:paddingRight="16dip">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="92dp"
|
||||
android:layout_height="92dp"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:contentDescription="@null"
|
||||
android:tint="@color/bigIconColor"
|
||||
android:src="@drawable/ic_file_download" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progress_bar"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="250dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminate="false" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/center_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/installing"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/buttons_panel"
|
||||
style="?android:attr/buttonBarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:measureWithLargestChild="true"
|
||||
android:orientation="horizontal"
|
||||
android:padding="8dip">
|
||||
|
||||
<View
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/cancel_button"
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="2"
|
||||
android:text="@string/cancel" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -1,113 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2016 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.
|
||||
-->
|
||||
|
||||
<!--
|
||||
Defines the layout of the splash screen that displays the security
|
||||
settings required for an application and requests the confirmation of the
|
||||
user before it is installed.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<!-- title bar -->
|
||||
<LinearLayout android:id="@+id/app_snippet"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?android:attr/actionBarSize"
|
||||
android:background="?android:attr/colorPrimary"
|
||||
android:elevation="@dimen/headerElevation"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_file_download"
|
||||
android:tint="?android:attr/colorAccent" />
|
||||
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="32dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:text="@string/app_name_unknown"
|
||||
android:textAppearance="?android:attr/titleTextStyle" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- content -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="16dip"
|
||||
android:paddingRight="16dip">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="92dp"
|
||||
android:layout_height="92dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:contentDescription="@null"
|
||||
android:tint="@color/bigIconColor"
|
||||
android:src="@drawable/ic_file_download" />
|
||||
|
||||
<ProgressBar
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="250dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminate="true" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/message_staging"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Bottom buttons -->
|
||||
<LinearLayout style="?android:attr/buttonBarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:padding="8dp">
|
||||
|
||||
<!-- spacer to push button to the right -->
|
||||
<View android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<Button android:id="@+id/cancel_button"
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="2"
|
||||
android:text="@string/cancel" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2016 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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout android:id="@+id/app_snippet"
|
||||
android:background="?android:attr/colorPrimary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?android:attr/actionBarSize"
|
||||
android:orientation="horizontal"
|
||||
android:elevation="@dimen/headerElevation"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<ImageView android:id="@+id/app_icon"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:scaleType="fitCenter" />
|
||||
|
||||
<TextView android:id="@+id/app_name"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/titleTextStyle"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="16dip"
|
||||
android:paddingRight="16dip">
|
||||
|
||||
<ImageView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:src="@drawable/ic_done_92"
|
||||
android:tint="@color/bigIconColor"
|
||||
android:contentDescription="@null" />
|
||||
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/install_done"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout style="?android:attr/buttonBarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:measureWithLargestChild="true"
|
||||
android:padding="8dip">
|
||||
|
||||
<!-- spacer to push buttons to the right -->
|
||||
<View android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<Button android:id="@+id/done_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/done"
|
||||
android:maxLines="2"
|
||||
style="?android:attr/buttonBarButtonStyle" />
|
||||
|
||||
<Button android:id="@+id/launch_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/launch"
|
||||
android:maxLines="2"
|
||||
style="?android:attr/buttonBarButtonStyle" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
23
packages/PackageInstaller/res/values-night/themes.xml
Normal file
23
packages/PackageInstaller/res/values-night/themes.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
|
||||
<style name="Theme.AlertDialogActivity"
|
||||
parent="@android:style/Theme.DeviceDefault.Dialog.Alert" />
|
||||
|
||||
</resources>
|
||||
@@ -36,11 +36,11 @@
|
||||
<!-- Message for updating an existing app [CHAR LIMIT=NONE] -->
|
||||
<string name="install_confirm_question_update">Do you want to install an update
|
||||
to this existing application? Your existing data will not
|
||||
be lost. The updated application will get access to:</string>
|
||||
be lost.</string>
|
||||
<!-- Message for updating an existing system app [CHAR LIMIT=NONE] -->
|
||||
<string name="install_confirm_question_update_system">Do you want to install an update
|
||||
to this built-in application? Your existing data will not
|
||||
be lost. The updated application will get access to:</string>
|
||||
be lost.</string>
|
||||
<!-- [CHAR LIMIT=100] -->
|
||||
<string name="install_failed">App not installed.</string>
|
||||
<!-- Reason displayed when installation fails because the package was blocked
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2010 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.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
|
||||
<style name="MediumText"
|
||||
parent="@android:style/TextAppearance.Medium">
|
||||
<item name="android:textColor">?android:attr/textColorPrimary</item>
|
||||
</style>
|
||||
|
||||
<style name="SmallText"
|
||||
parent="@android:style/TextAppearance.Small">
|
||||
<item name="android:textColor">?android:attr/textColorPrimary</item>
|
||||
</style>
|
||||
|
||||
<style name="TitleText">
|
||||
<item name="android:fontFamily">sans-serif-medium</item>
|
||||
<item name="android:textSize">20dp</item>
|
||||
<item name="android:textColor">?android:attr/textColorPrimary</item>
|
||||
</style>
|
||||
|
||||
<style name="ActionBar" parent="@android:style/Widget.Material.ActionBar.Solid">
|
||||
<item name="android:contentInsetStart">72dp</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
@@ -17,25 +17,11 @@
|
||||
|
||||
<resources>
|
||||
|
||||
<style name="DialogWhenLarge"
|
||||
parent="@android:style/Theme.DeviceDefault.Light.NoActionBar">
|
||||
<item name="android:textAppearanceMedium">@style/MediumText</item>
|
||||
<item name="android:textAppearanceSmall">@style/SmallText</item>
|
||||
<item name="android:titleTextStyle">@style/TitleText</item>
|
||||
</style>
|
||||
|
||||
<style name="DialogWhenLargeNoAnimation" parent="DialogWhenLarge">
|
||||
<style name="Theme.AlertDialogActivity.NoAnimation">
|
||||
<item name="android:windowAnimationStyle">@null</item>
|
||||
</style>
|
||||
|
||||
<style name="AlertDialogActivity"
|
||||
parent="@android:style/Theme.DeviceDefault.Light.Panel">
|
||||
<item name="android:backgroundDimEnabled">true</item>
|
||||
</style>
|
||||
|
||||
<style name="Header.Settings"
|
||||
parent="@android:style/Theme.DeviceDefault.Settings">
|
||||
</style>
|
||||
|
||||
<style name="Theme.AlertDialogActivity"
|
||||
parent="@android:style/Theme.DeviceDefault.Light.Dialog.Alert" />
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -30,41 +30,49 @@ import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.widget.TextView;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.internal.app.AlertActivity;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Installation failed: Return status code to the caller or display failure UI to user
|
||||
*/
|
||||
public class InstallFailed extends Activity {
|
||||
public class InstallFailed extends AlertActivity {
|
||||
private static final String LOG_TAG = InstallFailed.class.getSimpleName();
|
||||
|
||||
/** Label of the app that failed to install */
|
||||
private CharSequence mLabel;
|
||||
|
||||
/**
|
||||
* Convert an package installer status code into the user friendly label.
|
||||
* Unhide the appropriate label for the statusCode.
|
||||
*
|
||||
* @param statusCode The status code from the package installer.
|
||||
*
|
||||
* @return The user friendly label for the status code
|
||||
*/
|
||||
private int getExplanationFromErrorCode(int statusCode) {
|
||||
private void setExplanationFromErrorCode(int statusCode) {
|
||||
Log.d(LOG_TAG, "Installation status code: " + statusCode);
|
||||
|
||||
View viewToEnable;
|
||||
switch (statusCode) {
|
||||
case PackageInstaller.STATUS_FAILURE_BLOCKED:
|
||||
return R.string.install_failed_blocked;
|
||||
viewToEnable = requireViewById(R.id.install_failed_blocked);
|
||||
break;
|
||||
case PackageInstaller.STATUS_FAILURE_CONFLICT:
|
||||
return R.string.install_failed_conflict;
|
||||
viewToEnable = requireViewById(R.id.install_failed_conflict);
|
||||
break;
|
||||
case PackageInstaller.STATUS_FAILURE_INCOMPATIBLE:
|
||||
return R.string.install_failed_incompatible;
|
||||
viewToEnable = requireViewById(R.id.install_failed_incompatible);
|
||||
break;
|
||||
case PackageInstaller.STATUS_FAILURE_INVALID:
|
||||
return R.string.install_failed_invalid_apk;
|
||||
viewToEnable = requireViewById(R.id.install_failed_invalid_apk);
|
||||
break;
|
||||
default:
|
||||
return R.string.install_failed;
|
||||
viewToEnable = requireViewById(R.id.install_failed);
|
||||
break;
|
||||
}
|
||||
|
||||
viewToEnable.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -89,8 +97,6 @@ public class InstallFailed extends Activity {
|
||||
.getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO);
|
||||
Uri packageURI = intent.getData();
|
||||
|
||||
setContentView(R.layout.install_failed);
|
||||
|
||||
// Set header icon and title
|
||||
PackageUtil.AppSnippet as;
|
||||
PackageManager pm = getPackageManager();
|
||||
@@ -106,7 +112,12 @@ public class InstallFailed extends Activity {
|
||||
// Store label for dialog
|
||||
mLabel = as.label;
|
||||
|
||||
PackageUtil.initSnippetForNewApp(this, as, R.id.app_snippet);
|
||||
mAlert.setIcon(as.icon);
|
||||
mAlert.setTitle(as.label);
|
||||
mAlert.setView(R.layout.install_content_view);
|
||||
mAlert.setButton(DialogInterface.BUTTON_POSITIVE, getString(R.string.done),
|
||||
(ignored, ignored2) -> finish(), null);
|
||||
setupAlert();
|
||||
|
||||
// Show out of space dialog if needed
|
||||
if (statusCode == PackageInstaller.STATUS_FAILURE_STORAGE) {
|
||||
@@ -114,11 +125,7 @@ public class InstallFailed extends Activity {
|
||||
}
|
||||
|
||||
// Get status messages
|
||||
((TextView) findViewById(R.id.simple_status)).setText(
|
||||
getExplanationFromErrorCode(statusCode));
|
||||
|
||||
// Set up "done" button
|
||||
findViewById(R.id.done_button).setOnClickListener(view -> finish());
|
||||
setExplanationFromErrorCode(statusCode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,8 +19,8 @@ package com.android.packageinstaller;
|
||||
import static android.content.pm.PackageInstaller.SessionParams.UID_UNKNOWN;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.app.Activity;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInstaller;
|
||||
@@ -30,9 +30,11 @@ import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
import com.android.internal.app.AlertActivity;
|
||||
import com.android.internal.content.PackageHelper;
|
||||
|
||||
import java.io.File;
|
||||
@@ -47,7 +49,7 @@ import java.io.OutputStream;
|
||||
* <p>This has two phases: First send the data to the package manager, then wait until the package
|
||||
* manager processed the result.</p>
|
||||
*/
|
||||
public class InstallInstalling extends Activity {
|
||||
public class InstallInstalling extends AlertActivity {
|
||||
private static final String LOG_TAG = InstallInstalling.class.getSimpleName();
|
||||
|
||||
private static final String SESSION_ID = "com.android.packageinstaller.SESSION_ID";
|
||||
@@ -78,11 +80,31 @@ public class InstallInstalling extends Activity {
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.install_installing);
|
||||
|
||||
ApplicationInfo appInfo = getIntent()
|
||||
.getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO);
|
||||
mPackageURI = getIntent().getData();
|
||||
final File sourceFile = new File(mPackageURI.getPath());
|
||||
PackageUtil.AppSnippet as = PackageUtil.getAppSnippet(this, appInfo, sourceFile);
|
||||
|
||||
mAlert.setIcon(as.icon);
|
||||
mAlert.setTitle(as.label);
|
||||
mAlert.setView(R.layout.install_content_view);
|
||||
mAlert.setButton(DialogInterface.BUTTON_NEGATIVE, getString(R.string.cancel),
|
||||
(ignored, ignored2) -> {
|
||||
if (mInstallingTask != null) {
|
||||
mInstallingTask.cancel(true);
|
||||
}
|
||||
|
||||
if (mSessionId > 0) {
|
||||
getPackageManager().getPackageInstaller().abandonSession(mSessionId);
|
||||
mSessionId = 0;
|
||||
}
|
||||
|
||||
setResult(RESULT_CANCELED);
|
||||
finish();
|
||||
}, null);
|
||||
setupAlert();
|
||||
requireViewById(R.id.installing).setVisibility(View.VISIBLE);
|
||||
|
||||
if ("package".equals(mPackageURI.getScheme())) {
|
||||
try {
|
||||
@@ -92,10 +114,6 @@ public class InstallInstalling extends Activity {
|
||||
launchFailure(PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null);
|
||||
}
|
||||
} else {
|
||||
final File sourceFile = new File(mPackageURI.getPath());
|
||||
PackageUtil.initSnippetForNewApp(this, PackageUtil.getAppSnippet(this, appInfo,
|
||||
sourceFile), R.id.app_snippet);
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
mSessionId = savedInstanceState.getInt(SESSION_ID);
|
||||
mInstallId = savedInstanceState.getInt(INSTALL_ID);
|
||||
@@ -153,21 +171,7 @@ public class InstallInstalling extends Activity {
|
||||
}
|
||||
}
|
||||
|
||||
mCancelButton = (Button) findViewById(R.id.cancel_button);
|
||||
|
||||
mCancelButton.setOnClickListener(view -> {
|
||||
if (mInstallingTask != null) {
|
||||
mInstallingTask.cancel(true);
|
||||
}
|
||||
|
||||
if (mSessionId > 0) {
|
||||
getPackageManager().getPackageInstaller().abandonSession(mSessionId);
|
||||
mSessionId = 0;
|
||||
}
|
||||
|
||||
setResult(RESULT_CANCELED);
|
||||
finish();
|
||||
});
|
||||
mCancelButton = mAlert.getButton(DialogInterface.BUTTON_NEGATIVE);
|
||||
|
||||
mSessionCallback = new InstallSessionCallback();
|
||||
}
|
||||
@@ -307,7 +311,7 @@ public class InstallInstalling extends Activity {
|
||||
@Override
|
||||
public void onProgressChanged(int sessionId, float progress) {
|
||||
if (sessionId == mSessionId) {
|
||||
ProgressBar progressBar = (ProgressBar)findViewById(R.id.progress_bar);
|
||||
ProgressBar progressBar = requireViewById(R.id.progress);
|
||||
progressBar.setMax(Integer.MAX_VALUE);
|
||||
progressBar.setProgress((int) (Integer.MAX_VALUE * progress));
|
||||
}
|
||||
|
||||
@@ -29,6 +29,9 @@ import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.internal.app.AlertActivity;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
@@ -40,7 +43,7 @@ import java.io.OutputStream;
|
||||
* If a package gets installed from an content URI this step loads the package and turns it into
|
||||
* and installation from a file. Then it re-starts the installation as usual.
|
||||
*/
|
||||
public class InstallStaging extends Activity {
|
||||
public class InstallStaging extends AlertActivity {
|
||||
private static final String LOG_TAG = InstallStaging.class.getSimpleName();
|
||||
|
||||
private static final String STAGED_FILE = "STAGED_FILE";
|
||||
@@ -55,7 +58,19 @@ public class InstallStaging extends Activity {
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.install_staging);
|
||||
mAlert.setIcon(R.drawable.ic_file_download);
|
||||
mAlert.setTitle(getString(R.string.app_name_unknown));
|
||||
mAlert.setView(R.layout.install_content_view);
|
||||
mAlert.setButton(DialogInterface.BUTTON_NEGATIVE, getString(R.string.cancel),
|
||||
(ignored, ignored2) -> {
|
||||
if (mStagingTask != null) {
|
||||
mStagingTask.cancel(true);
|
||||
}
|
||||
setResult(RESULT_CANCELED);
|
||||
finish();
|
||||
}, null);
|
||||
setupAlert();
|
||||
requireViewById(R.id.staging).setVisibility(View.VISIBLE);
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
mStagedFile = new File(savedInstanceState.getString(STAGED_FILE));
|
||||
@@ -64,14 +79,6 @@ public class InstallStaging extends Activity {
|
||||
mStagedFile = null;
|
||||
}
|
||||
}
|
||||
|
||||
findViewById(R.id.cancel_button).setOnClickListener(view -> {
|
||||
if (mStagingTask != null) {
|
||||
mStagingTask.cancel(true);
|
||||
}
|
||||
setResult(RESULT_CANCELED);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.packageinstaller;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.Activity;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
@@ -26,15 +27,18 @@ import android.content.pm.ResolveInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
import com.android.internal.app.AlertActivity;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Finish installation: Return status code to the caller or display "success" UI to user
|
||||
*/
|
||||
public class InstallSuccess extends Activity {
|
||||
public class InstallSuccess extends AlertActivity {
|
||||
private static final String LOG_TAG = InstallSuccess.class.getSimpleName();
|
||||
|
||||
@Override
|
||||
@@ -53,8 +57,6 @@ public class InstallSuccess extends Activity {
|
||||
intent.getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO);
|
||||
Uri packageURI = intent.getData();
|
||||
|
||||
setContentView(R.layout.install_success);
|
||||
|
||||
// Set header icon and title
|
||||
PackageUtil.AppSnippet as;
|
||||
PackageManager pm = getPackageManager();
|
||||
@@ -67,16 +69,20 @@ public class InstallSuccess extends Activity {
|
||||
as = PackageUtil.getAppSnippet(this, appInfo, sourceFile);
|
||||
}
|
||||
|
||||
PackageUtil.initSnippetForNewApp(this, as, R.id.app_snippet);
|
||||
|
||||
// Set up "done" button
|
||||
findViewById(R.id.done_button).setOnClickListener(view -> {
|
||||
if (appInfo.packageName != null) {
|
||||
Log.i(LOG_TAG, "Finished installing " + appInfo.packageName);
|
||||
}
|
||||
finish();
|
||||
});
|
||||
|
||||
mAlert.setIcon(as.icon);
|
||||
mAlert.setTitle(as.label);
|
||||
mAlert.setView(R.layout.install_content_view);
|
||||
mAlert.setButton(DialogInterface.BUTTON_POSITIVE, getString(R.string.launch), null,
|
||||
null);
|
||||
mAlert.setButton(DialogInterface.BUTTON_NEGATIVE, getString(R.string.done),
|
||||
(ignored, ignored2) -> {
|
||||
if (appInfo.packageName != null) {
|
||||
Log.i(LOG_TAG, "Finished installing " + appInfo.packageName);
|
||||
}
|
||||
finish();
|
||||
}, null);
|
||||
setupAlert();
|
||||
requireViewById(R.id.install_success).setVisibility(View.VISIBLE);
|
||||
// Enable or disable "launch" button
|
||||
Intent launchIntent = getPackageManager().getLaunchIntentForPackage(
|
||||
appInfo.packageName);
|
||||
@@ -89,7 +95,7 @@ public class InstallSuccess extends Activity {
|
||||
}
|
||||
}
|
||||
|
||||
Button launchButton = (Button)findViewById(R.id.launch_button);
|
||||
Button launchButton = mAlert.getButton(DialogInterface.BUTTON_POSITIVE);
|
||||
if (enabled) {
|
||||
launchButton.setOnClickListener(view -> {
|
||||
try {
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* 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.android.packageinstaller;
|
||||
|
||||
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
|
||||
class OverlayTouchActivity extends Activity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
getWindow().addPrivateFlags(PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
*/
|
||||
package com.android.packageinstaller;
|
||||
|
||||
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.StringRes;
|
||||
@@ -45,9 +47,9 @@ import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.app.AlertActivity;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@@ -61,7 +63,7 @@ import java.io.File;
|
||||
* Based on the user response the package is then installed by launching InstallAppConfirm
|
||||
* sub activity. All state transitions are handled in this activity
|
||||
*/
|
||||
public class PackageInstallerActivity extends OverlayTouchActivity implements OnClickListener {
|
||||
public class PackageInstallerActivity extends AlertActivity {
|
||||
private static final String TAG = "PackageInstaller";
|
||||
|
||||
private static final int REQUEST_TRUST_EXTERNAL_SOURCE = 1;
|
||||
@@ -95,7 +97,6 @@ public class PackageInstallerActivity extends OverlayTouchActivity implements On
|
||||
|
||||
// Buttons to indicate user acceptance
|
||||
private Button mOk;
|
||||
private Button mCancel;
|
||||
|
||||
private PackageUtil.AppSnippet mAppSnippet;
|
||||
|
||||
@@ -119,18 +120,18 @@ public class PackageInstallerActivity extends OverlayTouchActivity implements On
|
||||
private boolean mEnableOk = false;
|
||||
|
||||
private void startInstallConfirm() {
|
||||
int msg;
|
||||
View viewToEnable;
|
||||
|
||||
if (mAppInfo != null) {
|
||||
msg = (mAppInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0
|
||||
? R.string.install_confirm_question_update_system
|
||||
: R.string.install_confirm_question_update;
|
||||
viewToEnable = (mAppInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0
|
||||
? requireViewById(R.id.install_confirm_question_update_system)
|
||||
: requireViewById(R.id.install_confirm_question_update);
|
||||
} else {
|
||||
// This is a new application with no permissions.
|
||||
msg = R.string.install_confirm_question;
|
||||
viewToEnable = requireViewById(R.id.install_confirm_question);
|
||||
}
|
||||
|
||||
((TextView) findViewById(R.id.install_confirm_question)).setText(msg);
|
||||
viewToEnable.setVisibility(View.VISIBLE);
|
||||
|
||||
mEnableOk = true;
|
||||
mOk.setEnabled(true);
|
||||
@@ -280,6 +281,8 @@ public class PackageInstallerActivity extends OverlayTouchActivity implements On
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle icicle) {
|
||||
getWindow().addPrivateFlags(PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
|
||||
|
||||
super.onCreate(null);
|
||||
|
||||
if (icicle != null) {
|
||||
@@ -344,7 +347,7 @@ public class PackageInstallerActivity extends OverlayTouchActivity implements On
|
||||
|
||||
// load dummy layout with OK button disabled until we override this layout in
|
||||
// startInstallConfirm
|
||||
bindUi(R.layout.install_confirm);
|
||||
bindUi();
|
||||
checkIfAllowedAndInitiateInstall();
|
||||
}
|
||||
|
||||
@@ -374,17 +377,34 @@ public class PackageInstallerActivity extends OverlayTouchActivity implements On
|
||||
outState.putBoolean(ALLOW_UNKNOWN_SOURCES_KEY, mAllowUnknownSources);
|
||||
}
|
||||
|
||||
private void bindUi(int layout) {
|
||||
setContentView(layout);
|
||||
|
||||
mOk = (Button) findViewById(R.id.ok_button);
|
||||
mCancel = (Button)findViewById(R.id.cancel_button);
|
||||
mOk.setOnClickListener(this);
|
||||
mCancel.setOnClickListener(this);
|
||||
private void bindUi() {
|
||||
mAlert.setIcon(mAppSnippet.icon);
|
||||
mAlert.setTitle(mAppSnippet.label);
|
||||
mAlert.setView(R.layout.install_content_view);
|
||||
mAlert.setButton(DialogInterface.BUTTON_POSITIVE, getString(R.string.install),
|
||||
(ignored, ignored2) -> {
|
||||
if (mOk.isEnabled()) {
|
||||
if (mSessionId != -1) {
|
||||
mInstaller.setPermissionsResult(mSessionId, true);
|
||||
finish();
|
||||
} else {
|
||||
startInstall();
|
||||
}
|
||||
}
|
||||
}, null);
|
||||
mAlert.setButton(DialogInterface.BUTTON_NEGATIVE, getString(R.string.cancel),
|
||||
(ignored, ignored2) -> {
|
||||
// Cancel and finish
|
||||
setResult(RESULT_CANCELED);
|
||||
if (mSessionId != -1) {
|
||||
mInstaller.setPermissionsResult(mSessionId, false);
|
||||
}
|
||||
finish();
|
||||
}, null);
|
||||
setupAlert();
|
||||
|
||||
mOk = mAlert.getButton(DialogInterface.BUTTON_POSITIVE);
|
||||
mOk.setEnabled(false);
|
||||
|
||||
PackageUtil.initSnippetForNewApp(this, mAppSnippet, R.id.app_snippet);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -525,26 +545,6 @@ public class PackageInstallerActivity extends OverlayTouchActivity implements On
|
||||
super.onBackPressed();
|
||||
}
|
||||
|
||||
public void onClick(View v) {
|
||||
if (v == mOk) {
|
||||
if (mOk.isEnabled()) {
|
||||
if (mSessionId != -1) {
|
||||
mInstaller.setPermissionsResult(mSessionId, true);
|
||||
finish();
|
||||
} else {
|
||||
startInstall();
|
||||
}
|
||||
}
|
||||
} else if (v == mCancel) {
|
||||
// Cancel and finish
|
||||
setResult(RESULT_CANCELED);
|
||||
if (mSessionId != -1) {
|
||||
mInstaller.setPermissionsResult(mSessionId, false);
|
||||
}
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
private void startInstall() {
|
||||
// Start subactivity to actually install the application
|
||||
Intent newIntent = new Intent();
|
||||
|
||||
@@ -108,26 +108,6 @@ public class PackageUtil {
|
||||
icon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to display application snippet of a new package.
|
||||
* The content view should have been set on context before invoking this method.
|
||||
* appSnippet view should include R.id.app_icon and R.id.app_name
|
||||
* defined on it.
|
||||
*
|
||||
* @param pContext context of package that can load the resources
|
||||
* @param as The resources to be loaded
|
||||
* @param snippetId view id of app snippet view
|
||||
*/
|
||||
@NonNull public static View initSnippetForNewApp(@NonNull Activity pContext,
|
||||
@NonNull AppSnippet as, int snippetId) {
|
||||
View appSnippet = pContext.findViewById(snippetId);
|
||||
if (as.icon != null) {
|
||||
((ImageView) appSnippet.findViewById(R.id.app_icon)).setImageDrawable(as.icon);
|
||||
}
|
||||
((TextView)appSnippet.findViewById(R.id.app_name)).setText(as.label);
|
||||
return appSnippet;
|
||||
}
|
||||
|
||||
static public class AppSnippet {
|
||||
@NonNull public CharSequence label;
|
||||
@Nullable public Drawable icon;
|
||||
|
||||
Reference in New Issue
Block a user