1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.pm;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 
22 import com.android.internal.annotations.VisibleForTesting;
23 import com.android.server.pm.permission.LegacyPermissionState;
24 import com.android.server.pm.pkg.mutate.PackageStateMutator;
25 import com.android.server.utils.Snappable;
26 import com.android.server.utils.Watchable;
27 import com.android.server.utils.WatchableImpl;
28 import com.android.server.utils.Watcher;
29 
30 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
31 public abstract class SettingBase implements Watchable, Snappable {
32 
33     // TODO: Remove in favor of individual boolean APIs. It's not clear what flag values are saved
34     //  and bugs exist where callers query for an unsaved flag.
35     private int mPkgFlags;
36     private int mPkgPrivateFlags;
37 
38     /**
39      * Watchable machinery
40      */
41     private final Watchable mWatchable = new WatchableImpl();
42 
43     /**
44      * Ensures an observer is in the list, exactly once. The observer cannot be null.  The
45      * function quietly returns if the observer is already in the list.
46      *
47      * @param observer The {@link Watcher} to be notified when the {@link Watchable} changes.
48      */
49     @Override
registerObserver(@onNull Watcher observer)50     public void registerObserver(@NonNull Watcher observer) {
51         mWatchable.registerObserver(observer);
52     }
53 
54     /**
55      * Ensures an observer is not in the list. The observer must not be null.  The function
56      * quietly returns if the objserver is not in the list.
57      *
58      * @param observer The {@link Watcher} that should not be in the notification list.
59      */
60     @Override
unregisterObserver(@onNull Watcher observer)61     public void unregisterObserver(@NonNull Watcher observer) {
62         mWatchable.unregisterObserver(observer);
63     }
64 
65     /**
66      * Return true if the {@link Watcher) is a registered observer.
67      * @param observer A {@link Watcher} that might be registered
68      * @return true if the observer is registered with this {@link Watchable}.
69      */
70     @Override
isRegisteredObserver(@onNull Watcher observer)71     public boolean isRegisteredObserver(@NonNull Watcher observer) {
72         return mWatchable.isRegisteredObserver(observer);
73     }
74 
75     /**
76      * Invokes {@link Watcher#onChange} on each registered observer.  The method can be called
77      * with the {@link Watchable} that generated the event.  In a tree of {@link Watchable}s, this
78      * is generally the first (deepest) {@link Watchable} to detect a change.
79      *
80      * @param what The {@link Watchable} that generated the event.
81      */
82     @Override
dispatchChange(@ullable Watchable what)83     public void dispatchChange(@Nullable Watchable what) {
84         mWatchable.dispatchChange(what);
85     }
86 
87     /**
88      * Notify listeners that this object has changed.
89      */
onChanged()90     public void onChanged() {
91         PackageStateMutator.onPackageStateChanged();
92         dispatchChange(this);
93     }
94 
95     /**
96      * The legacy permission state that is read from package settings persistence for migration.
97      * This state here can not reflect the current permission state and should not be used for
98      * purposes other than migration.
99      */
100     @Deprecated
101     protected final LegacyPermissionState mLegacyPermissionsState = new LegacyPermissionState();
102 
SettingBase(int pkgFlags, int pkgPrivateFlags)103     SettingBase(int pkgFlags, int pkgPrivateFlags) {
104         setFlags(pkgFlags);
105         setPrivateFlags(pkgPrivateFlags);
106     }
107 
SettingBase(@ullable SettingBase orig)108     SettingBase(@Nullable SettingBase orig) {
109         if (orig != null) {
110             copySettingBase(orig);
111         }
112     }
113 
copySettingBase(SettingBase orig)114     public final void copySettingBase(SettingBase orig) {
115         mPkgFlags = orig.mPkgFlags;
116         mPkgPrivateFlags = orig.mPkgPrivateFlags;
117         mLegacyPermissionsState.copyFrom(orig.mLegacyPermissionsState);
118         onChanged();
119     }
120 
121     @Deprecated
getLegacyPermissionState()122     public LegacyPermissionState getLegacyPermissionState() {
123         return mLegacyPermissionsState;
124     }
125 
setFlags(int pkgFlags)126     public SettingBase setFlags(int pkgFlags) {
127         this.mPkgFlags = pkgFlags;
128         onChanged();
129         return this;
130     }
131 
setPrivateFlags(int pkgPrivateFlags)132     public SettingBase setPrivateFlags(int pkgPrivateFlags) {
133         this.mPkgPrivateFlags = pkgPrivateFlags;
134         onChanged();
135         return this;
136     }
137 
getFlags()138     public int getFlags() {
139         return mPkgFlags;
140     }
141 
getPrivateFlags()142     public int getPrivateFlags() {
143         return mPkgPrivateFlags;
144     }
145 }
146