• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.car.projection;
18 
19 import android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.annotation.SystemApi;
23 import android.app.ActivityOptions;
24 import android.car.annotation.AddedInOrBefore;
25 import android.car.builtin.app.ActivityManagerHelper;
26 import android.content.ComponentName;
27 import android.os.Bundle;
28 
29 import java.lang.annotation.Retention;
30 import java.lang.annotation.RetentionPolicy;
31 
32 /**
33  * This class holds OEM customization for projection receiver app.  It is created by Car Service.
34  *
35  * @hide
36  */
37 @SystemApi
38 public class ProjectionOptions {
39     private static final String KEY_PREFIX = "android.car.projection.";
40 
41     /** Immersive full screen mode (all system bars are hidden) */
42     @AddedInOrBefore(majorVersion = 33)
43     public static final int UI_MODE_FULL_SCREEN = 0;
44 
45     /** Show status and navigation bars. */
46     @AddedInOrBefore(majorVersion = 33)
47     public static final int UI_MODE_BLENDED = 1;
48 
49     private static final int UI_MODE_DEFAULT = UI_MODE_FULL_SCREEN;
50 
51     /** @hide */
52     @IntDef({UI_MODE_FULL_SCREEN, UI_MODE_BLENDED})
53     @Retention(RetentionPolicy.SOURCE)
54     public @interface ProjectionUiMode {}
55 
56     /** Indicates that head unit didn't specify information about access point mode.  This value
57      * can only be seen on Android SDK 31 and below. */
58     @AddedInOrBefore(majorVersion = 33)
59     public static final int AP_MODE_NOT_SPECIFIED = 0;
60 
61     /** Projection access point was created such that it may provide Internet access. */
62     @AddedInOrBefore(majorVersion = 33)
63     public static final int AP_MODE_TETHERED = 1;
64 
65     /**
66      * Projection access point was created as local-only hotspot, without Internet access and the
67      * credentials will be auto-generated for every access point initialization.
68      */
69     @AddedInOrBefore(majorVersion = 33)
70     public static final int AP_MODE_LOHS_DYNAMIC_CREDENTIALS = 2;
71 
72     /**
73      * Projection access point was created as local-only hotspot, without Internet access and the
74      * credentials will persist reboots.  Credentials still can be reseted by user or app request.
75      */
76     @AddedInOrBefore(majorVersion = 33)
77     public static final int AP_MODE_LOHS_STATIC_CREDENTIALS = 3;
78 
79     /** @hide */
80     @IntDef({AP_MODE_NOT_SPECIFIED, AP_MODE_TETHERED, AP_MODE_LOHS_DYNAMIC_CREDENTIALS,
81             AP_MODE_LOHS_STATIC_CREDENTIALS})
82     @Retention(RetentionPolicy.SOURCE)
83     public @interface ProjectionAccessPointMode {}
84 
85     private static final String KEY_ACTIVITY_OPTIONS = KEY_PREFIX + "activityOptions";
86     private static final String KEY_UI_MODE = KEY_PREFIX + "systemUiFlags";
87     private static final String KEY_CONSENT_ACTIVITY = KEY_PREFIX + "consentActivity";
88     private static final String KEY_ACCESS_POINT_MODE = KEY_PREFIX + "ap_mode";
89 
90     private final ActivityOptions mActivityOptions;
91     private final int mUiMode;
92     private final ComponentName mConsentActivity;
93     private final int mApMode;
94 
95     /**
96      * Creates new instance for given {@code Bundle}
97      *
98      * @param bundle contains OEM specific information
99      */
ProjectionOptions(Bundle bundle)100     public ProjectionOptions(Bundle bundle) {
101         Bundle activityOptionsBundle = bundle.getBundle(KEY_ACTIVITY_OPTIONS);
102         mActivityOptions = activityOptionsBundle != null
103                 ? ActivityManagerHelper.createActivityOptions(activityOptionsBundle) : null;
104         mUiMode = bundle.getInt(KEY_UI_MODE, UI_MODE_DEFAULT);
105         mConsentActivity = bundle.getParcelable(KEY_CONSENT_ACTIVITY);
106         mApMode = bundle.getInt(KEY_ACCESS_POINT_MODE, AP_MODE_NOT_SPECIFIED);
107     }
108 
ProjectionOptions(Builder builder)109     private ProjectionOptions(Builder builder) {
110         mActivityOptions = builder.mActivityOptions;
111         mUiMode = builder.mUiMode;
112         mConsentActivity = builder.mConsentActivity;
113         mApMode = builder.mApMode;
114     }
115 
116     /**
117      * Returns combination of flags from View.SYSTEM_UI_FLAG_* which will be used by projection
118      * receiver app during rendering.
119      */
120     @AddedInOrBefore(majorVersion = 33)
getUiMode()121     public @ProjectionUiMode int getUiMode() {
122         return mUiMode;
123     }
124 
125     /**
126      * Returns projection access point mode.
127      *
128      * <p>The result could be one of the following values:
129      * <ul>
130      *     <li>{@link #AP_MODE_NOT_SPECIFIED}</li>
131      *     <li>{@link #AP_MODE_TETHERED}</li>
132      *     <li>{@link #AP_MODE_LOHS_DYNAMIC_CREDENTIALS}</li>
133      *     <li>{@link #AP_MODE_LOHS_STATIC_CREDENTIALS}</li>
134      * </ul>
135      */
136     @AddedInOrBefore(majorVersion = 33)
getProjectionAccessPointMode()137     public @ProjectionAccessPointMode int getProjectionAccessPointMode() {
138         return mApMode;
139     }
140 
141     /**
142      * Returns {@link ActivityOptions} that needs to be applied when launching projection activity
143      */
144     @AddedInOrBefore(majorVersion = 33)
getActivityOptions()145     public @Nullable ActivityOptions getActivityOptions() {
146         return mActivityOptions;
147     }
148 
149     /**
150      * Returns package/activity name of the consent activity provided by OEM which needs to be shown
151      * for all mobile devices unless user accepted the consent.
152      *
153      * <p>If the method returns null then consent dialog should not be shown.
154      */
155     @AddedInOrBefore(majorVersion = 33)
getConsentActivity()156     public @Nullable ComponentName getConsentActivity() {
157         return mConsentActivity;
158     }
159 
160     /** Converts current object to {@link Bundle} */
161     @AddedInOrBefore(majorVersion = 33)
toBundle()162     public @NonNull Bundle toBundle() {
163         Bundle bundle = new Bundle();
164         if (mActivityOptions != null) {
165             bundle.putBundle(KEY_ACTIVITY_OPTIONS, mActivityOptions.toBundle());
166         }
167         bundle.putParcelable(KEY_CONSENT_ACTIVITY, mConsentActivity);
168         if (mUiMode != UI_MODE_DEFAULT) {
169             bundle.putInt(KEY_UI_MODE, mUiMode);
170         }
171         bundle.putInt(KEY_ACCESS_POINT_MODE, mApMode);
172         return bundle;
173     }
174 
175     /** @hide */
176     @AddedInOrBefore(majorVersion = 33)
builder()177     public static Builder builder() {
178         return new Builder();
179     }
180 
181     /** @hide */
182     public static class Builder {
183         private ActivityOptions mActivityOptions;
184         private int mUiMode = UI_MODE_DEFAULT;
185         private ComponentName mConsentActivity;
186         private int mApMode = AP_MODE_NOT_SPECIFIED;
187 
188         /** Sets {@link ActivityOptions} to launch projection activity. */
189         @AddedInOrBefore(majorVersion = 33)
setProjectionActivityOptions(ActivityOptions activityOptions)190         public Builder setProjectionActivityOptions(ActivityOptions activityOptions) {
191             mActivityOptions = activityOptions;
192             return this;
193         }
194 
195         /** Set UI for projection activity. It can be one of {@code UI_MODE_*} constants. */
196         @AddedInOrBefore(majorVersion = 33)
setUiMode(@rojectionUiMode int uiMode)197         public Builder setUiMode(@ProjectionUiMode int uiMode) {
198             mUiMode = uiMode;
199             return this;
200         }
201 
202         /** Sets consent activity which will be shown before starting projection. */
203         @AddedInOrBefore(majorVersion = 33)
setConsentActivity(ComponentName consentActivity)204         public Builder setConsentActivity(ComponentName consentActivity) {
205             mConsentActivity = consentActivity;
206             return this;
207         }
208 
209         /** Sets projection access point mode */
210         @AddedInOrBefore(majorVersion = 33)
setAccessPointMode(@rojectionAccessPointMode int accessPointMode)211         public Builder setAccessPointMode(@ProjectionAccessPointMode int accessPointMode) {
212             this.mApMode = accessPointMode;
213             return this;
214         }
215 
216         /** Creates an instance of {@link android.car.projection.ProjectionOptions} */
217         @AddedInOrBefore(majorVersion = 33)
build()218         public ProjectionOptions build() {
219             return new ProjectionOptions(this);
220         }
221     }
222 
223     /** @hide */
224     @Override
225     @AddedInOrBefore(majorVersion = 33)
toString()226     public String toString() {
227         return toBundle().toString();
228     }
229 }
230